接着上一篇文章,在 shouldSkip 方法中已经将 Advice 通知方法生成了 Advisor 对象并且缓存好了
然后调用 getAdvicesAndAdvisorsForBean 方法去获取当前 Bean 的拦截器(也就是 Advice 通知),这个方法首先从缓存中获取到已经缓存好的 List<Advisor>
,然后挨个的检查对应的 Advisor,这个方法首通过反射获取当前类的所有的方法(包括父类)然后调用 matches 方法从 Advisor 中取出 Pointcut 表达式进行匹配检查,只要有一个方法满足条件么就返回为 ture 表示需要创建代理对象
然后回到 AbstractAutoProxyCreator 的 wrapIfNecessary 方法中,当 specificInterceptors 不为 null 的时候表明了需要创建代理,就会调用 createProxy 方法
这里又会调用 buildAdvisors 主要是对默认的一些拦截器做一些包装和检测
然后我们回到 AbstractAutoProxyCreator 的 createProxy 方法,在最后一步会调用 proxyFactory.getProxy(getProxyClassLoader()); 来创建代理对象
我们使用 AOP 的时候发现这里的 proxyTargetClass 始终返回为 true,它的这个值是来源于 AbstractAutoProxyCreator 的 createProxy 方法中的 proxyFactory.copyFrom(this); 这个方法,当前 this 对象是 AnnotationAwareAspectJAutoProxyCreator
随后判断如果我们的类如果是接口或者是一个 ProxyClass 的话就返回 JDK 动态代理对象,否则的是就返回 CGLIB 的动态代理对象
到此回到 AbstractAutowireCapableBeanFactory 的 doCreateBean 的 initializeBean 方法调用中返回了代理对象
然后我们返回到 AbstractFactory 的 doGetBean 方法,再看看这段逻辑
他不是直接调用 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 的实例创建就算完成了