-

Spring源码解析(四)-Spring使用cglib创建代理对象

2021-11-18

Spring源码解析


一、ProxyFactory

Spring通过ProxyFactory创建代理对象,可以看Spring源码解析(三)

// 创建代理对象public Object getProxy() {return createAopProxy().getProxy();}
// 创建代理对象protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// config.isProxyTargetClass() 是否设置了proxyTargetClass为true // hasNoUserSuppliedProxyInterfaces 是否没有实现任何接口if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}// 代理类本身是个接口需要用jdk代理if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}// 其余使用cglibreturn new ObjenesisCglibAopProxy(config);}else {return new JdkDynamicAopProxy(config);}

从以上可以看出一般情况下使用jdk代理,除非设置了proxyTargetClass为true或者没有实现接口,所有我们主要看下proxyTargetClass在那个位置设置

在这里插入图片描述

获取注解属性proxyTargetClass为true的时候执行AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry),而proxyTargetClass是@EnableTransactionManagement的属性

在这里插入图片描述

AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry)

public static final String AUTO_PROXY_CREATOR_BEAN_NAME ="org.springframework.aop.config.internalAutoProxyCreator";// 强制使用cglib代理public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {// 判断是否有传教代理的Creatorif (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);// 为代理设置proxyTargetClass 设置为true definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);}}

从forceAutoProxyCreatorToUseClassProxying点击引用,看到AopAutoConfig也调用了该方法

在这里插入图片描述

ClassProxyingConfiguration

// 设置spring.aop.proxy-target-class = true的时候该类生效@Configuration(proxyBeanMethods = false)@ConditionalOnMissingClass("org.aspectj.weaver.Advice")@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)static class ClassProxyingConfiguration {ClassProxyingConfiguration(BeanFactory beanFactory) {if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;// 注册AutoProxyCreatorAopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);// 强制使用cglibAopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}}}

总结

当设置@EnableTransactionManagement的proxyTargetClass=true,或者spring.aop.proxy-target-class为true的时候使用cglib代理
阅读2
分享