转载

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

接着上一篇文章,在 shouldSkip 方法中已经将 Advice 通知方法生成了 Advisor 对象并且缓存好了

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

然后调用 getAdvicesAndAdvisorsForBean 方法去获取当前 Bean 的拦截器(也就是 Advice 通知),这个方法首先从缓存中获取到已经缓存好的 List<Advisor> ,然后挨个的检查对应的 Advisor,这个方法首通过反射获取当前类的所有的方法(包括父类)然后调用 matches 方法从 Advisor 中取出 Pointcut 表达式进行匹配检查,只要有一个方法满足条件么就返回为 ture 表示需要创建代理对象

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决
Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

然后回到 AbstractAutoProxyCreator 的 wrapIfNecessary 方法中,当 specificInterceptors 不为 null 的时候表明了需要创建代理,就会调用 createProxy 方法

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

这里又会调用 buildAdvisors 主要是对默认的一些拦截器做一些包装和检测

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决
Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

然后我们回到 AbstractAutoProxyCreator 的 createProxy 方法,在最后一步会调用 proxyFactory.getProxy(getProxyClassLoader()); 来创建代理对象

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决
Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

我们使用 AOP 的时候发现这里的 proxyTargetClass 始终返回为 true,它的这个值是来源于 AbstractAutoProxyCreator 的 createProxy 方法中的 proxyFactory.copyFrom(this); 这个方法,当前 this 对象是 AnnotationAwareAspectJAutoProxyCreator

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

随后判断如果我们的类如果是接口或者是一个 ProxyClass 的话就返回 JDK 动态代理对象,否则的是就返回 CGLIB 的动态代理对象

到此回到 AbstractAutowireCapableBeanFactory 的 doCreateBean 的 initializeBean 方法调用中返回了代理对象

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

然后我们返回到 AbstractFactory 的 doGetBean 方法,再看看这段逻辑

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

他不是直接调用 createBean 的是先调用了 getSingleton 方法

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

在这个方法中首先调用 singletonFactory.getObject 去调用 createBean 方法,然后检测到该对象是一个新的单例对象就调用 addSingleton 放入容器中

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

到此创建一个完整的 Bean 实例完成了,那么最后就还有一个问题就是,由于需要去解决循环依赖问题,导致在调用初始化方法前其实就将 Bean 实例放入到了早期 Bean 实例中,可能会导致注入的都不是代理对象

处理循环依赖时候是如何解决代理对象问题的

比如 A 依赖 B,B 又依赖 A;同时我们又定义了 AOP 逻辑包含到了 A 和 B 的方法它们需要被代理,前文讲过首先我们通过反射创建 A 的早期实例然后放入到 singletonFactories 中,然后再调用 populateBean 进行依赖注入的时候发现了 A 依赖于 B,这个时候就要开始 B 的实例化,这个时候在 AbstractBeanFactory 的 doGetBean 的 getSingleton 方法就能起到作用它能从 singletonFactories 创建出 A 实例来,这个时候创建出来的就是这个 A 代理对象,我们来看下它是如何做到的

首先在创建 singletonFactories 的时候是放入的一个 ObjectFactory 的实现

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决
Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

然后的调用 singletonFactories 中的 singleFactory.getObject 方法会调用到该方法

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

遍历 BeanPostProcessor 最终会调用 AnnotationAwareAspectJAutoProxyCreator 的 getEarlyBeanReference 方法

Spring AOP 源码解析(二),创建代理对象、循环依赖的代理对象如何解决

熟悉的地方又来了回到了 wrapIfNecessary 上面讲过的方法中了。最后由于 A 调用初始化方法针对代理对象来操作即可,这样一个完整的 Bean 的实例创建就算完成了

原文  https://juejin.im/post/5f097d246fb9a07eb90cb71b
正文到此结束
Loading...