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

建立代理对象

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

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

而后回到 AbstractAutoProxyCreator 的 wrapIfNecessary 方法中,当 specificInterceptors 不为 null 的时候代表了须要建立代理,就会调用 createProxy 方法this

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

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

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

随后判断若是咱们的类若是是接口或者是一个 ProxyClass 的话就返回 JDK 动态代理对象,不然的是就返回 CGLIB 的动态代理对象cdn

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

而后咱们返回到 AbstractFactory 的 doGetBean 方法,再看看这段逻辑blog

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

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

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

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

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

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

而后的调用 singletonFactories 中的 singleFactory.getObject 方法会调用到该方法
遍历 BeanPostProcessor 最终会调用 AnnotationAwareAspectJAutoProxyCreator 的 getEarlyBeanReference 方法

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

相关文章
相关标签/搜索