【Spring源码】22.AOP之代理对象的创建
前言
上一章我们讲了 , 在AbstractAutoProxyCreator类实现至BeanPostProcessor接口的postProcessAfterInitialization方法中,在遍历每一个正在实例化的bean时,会先解析容器类所有的beanNames对应的class,来创建并收集advisor对象。 并且会把当前beanClass 与 advisor对象集合进行匹配,如果匹配到了advisor对象,那么就说明 这个bean的某些方法时需要增强的,那么就会通过jdk动态代理或者cglib 来创建代理对象,实现aop。
接下来看看spring aop创建代理对象的具体过程。
![](https://img.haomeiwen.com/i23353704/e164c93ac6910ffd.png)
进入createProxy方法,可以看到会把 beanClass,beanName,以及命中的Advisor集合,以及原生bean 包装成SingletonTargetSource对象传进去
![](https://img.haomeiwen.com/i23353704/cc57892be7091eda.png)
1. proxyFactory对象的创建
createProxy方法会先常见一个ProxyFactory代理工厂对象,并且从AbstractAutoProxyCreator对象,复制一些属性进去
![](https://img.haomeiwen.com/i23353704/defc8ad751b7ea87.png)
![](https://img.haomeiwen.com/i23353704/f4a301e18e23a6d4.png)
1.1. 判断接口与更改proxyTargetClass属性值
这里最重要的属性是proxyTargetClass,将参与 决定使用jdk动态代理,还是cglib代理。
就是@EnableAspectJAutoProxy注解里的 proxyTargetClass 属性
@Component
@EnableAspectJAutoProxy(proxyTargetClass = false)
public class AopConfig {
}
如果是默认的false(默认),那么接下来会有一个判断的过程,有可能会被spring改成true
![](https://img.haomeiwen.com/i23353704/c61bc37f53a144d4.png)
evaluateProxyInterfaces方法会去判断 该beanClass 是否有实现接口
先是取出 beanClass 实现的所有接口
![](https://img.haomeiwen.com/i23353704/c4d55155fbd79c49.png)
然后遍历,遍历的过程中会判断 接口的合法性
![](https://img.haomeiwen.com/i23353704/9fd72544c8ec531f.png)
- isConfigurationCallbackInterface判断接口得不是 InitializingBean/ DisposableBean / Closeable/ AutoCloseable/ Aware 这几个接口,这是spring提供的接口
![](https://img.haomeiwen.com/i23353704/a4d386d1409a1758.png)
- isInternalLanguageInterface 判断 !( 接口名称.equals("groovy.lang.GroovyObject") ||接口名称.getName().endsWith(".cglib.proxy.Factory") || 接口名称.endsWith(".bytebuddy.MockAccess"));)
![](https://img.haomeiwen.com/i23353704/d1f623c86e37be7f.png)
这两个判断都 符合的话,hasReasonableProxyInterface变量会变成true, 并退出遍历
hasReasonableProxyInterface 为true的话, proxyTargetClass配置就还是false,不变
否则为false, 则会被 更改成 true
![](https://img.haomeiwen.com/i23353704/d3ef0ac4322b46e7.png)
1.2 proxyFactory其他属性赋值
判断完 ProxyTargetClass 属性后,对TargetSource 目标对象,advisor对象集合等属性进行赋值
![](https://img.haomeiwen.com/i23353704/709fb286b43e83ca.png)
2. 创建aop代理对象-AopProxy对象
proxyFactory对象 创建成功后,开始创建AopProxy对象
![](https://img.haomeiwen.com/i23353704/66563c041238bb06.png)
这个AopProxy对象啊,是spring的aop代理对象,它两个实现类
- 通过jdk动态代理实现的aop代理对象
- 通过cglib代理实现的aop代理对象
通过它可以创建jdk动态代理/cglib 代理对象
看createAopProxy(classLoader)方法
![](https://img.haomeiwen.com/i23353704/50c2174d040a5e50.png)
调用aop代理工厂对象 创建aop代理对象 : createAopProxy
这里注意,会传入 proxyFactory对象, proxyFactory对象是持有原生bean和该类匹配的所有切面对象的
![](https://img.haomeiwen.com/i23353704/afb9fded7eabecfe.png)
这里就有判断 具体是使用jdk动态代理还是cglib了
![](https://img.haomeiwen.com/i23353704/bddf67f23788afb5.png)
if ( 如果ProxyTargetClass配置的为true,
或者该类没有除 InitializingBean/ DisposableBean / Closeable/ AutoCloseable/ Aware 以外的接口-->ProxyTargetClass会被改成true,
或者 (如果 没有任何接口 或者 只实现了SpringProxy ){
if(该类 是否是接口,或者是 Proxy类型(该class就是jdk动态代理创建的))
那么还是会使用jdk动态代理
Else{
使用cglib
}
}else{
使用jdk动态代理
}
如何还要考虑是否代理,是否只实现SpringProxy接口 那样太复杂了 ,下面这个归纳一下就可以满足常用的情况了
proxyTargetClass=false(默认)
被代理类是否实现除 InitializingBean/ DisposableBean / Closeable/ AutoCloseable/ Aware 以外的接口:
是 jdk动态代理
否 proxyTargetClass会被改成true
proxyTargetClass=true
被代理类是否是接口||是否是代理类(一般无法满足)
是 : jdk动态代理
否 : cglib动态代理
不管是返回JdkDynamicAopProxy 还是 ObjenesisCglibAopProxy,都会传入 proxyFactory对象,在构造方法赋值给JdkDynamicAopProxy的 AdvisedSupport advised属性。
也就是 JdkDynamicAopProxy {
AdvisedSupport advised = proxyFactory{
advisors :所有的切面,
targetSource:被代理目标对象
proxyTargetClass :代理的方式
}
}
3. AopProxy对象创建jdk代理对象
如果是jdk动态代理,上面返回的是JdkDynamicAopProxy对象
来看下 是怎么生成代理对象的
代码回到这
![](https://img.haomeiwen.com/i23353704/b84c3e361d8da27b.png)
进入JdkDynamicAopProxy类的 getProxy方法
![](https://img.haomeiwen.com/i23353704/7b0f337b0af45f0b.png)
这里就是 按照jdk动态代理 的 模式 创建代理对象了,传入类加载器,实现的所有正常接口,InvocationHandler对象,创建代理对象
这里值得注意的是传入的 InvocationHandler对象就是 JdkDynamicAopProxy对象
那么JdkDynamicAopProxy 肯定实现了InvocationHandler接口,那么肯定会实现invoke方法,具体的增强逻辑 就在invoke方法里了。
![](https://img.haomeiwen.com/i23353704/0e52abafb56e1d94.png)
并且他的AdvisedSupport advised 属性是 proxyFactory{
advisors :所有的切面,
targetSource:被代理目标对象
proxyTargetClass :代理的方式
}
当方法执行的时候就会执行 InvokeHandle的invoke方法,取出AdvisedSupport advised属性里的advisors进行方法级别的匹配,并调用advice,进行增强。
![](https://img.haomeiwen.com/i23353704/8acb891eddae7ec9.png)