概述
在上一讲中,我们通过简单的人工分析,为AnnotationAwareAspectJAutoProxyCreator这个类中有关后置处理器以及自动装配BeanFactoryAware接口的那些方法都打上了一些断点,而且还为MainConfigOfAOP配置类中的两个方法打上了断点。
接下来,我们就以debug模式来运行IOCTest_AOP测试类,仔细分析一下整个流程。
创建和注册AnnotationAwareAspectJAutoProxyCreator的过程
以debug模式来运行IOCTest_AOP测试类之后,会先来到AbstractAdvisorAutoProxyCreator类的setBeanFactory()方法中,如下图所示。
可以看到这一步是传入主配置类来创建IOC容器,怎么创建的呢?我们点击方法调用栈中test01()方法上面的那个方法,就来到下面这个地方了。
可以看到,传入主配置类来创建IOC容器使用的是AnnotationConfigApplicationContext类的有参构造器,具体分为下面三步:
- 首先使用无参构造器创建对象。
- 再来把主配置类注册进来。
- 最后调用refresh()方法刷新容器,刷新容器就是要把容器中的所有bean都创建出来,也就是说这就像初始化容器一样。
接下来,我们来看看容器刷新是怎么做的?
其中,该refresh()方法中有一行非常重要的代码,那就是:
registerBeanPostProcessors(beanFactory);
即注册bean的后置处理器。它的作用是用来方便拦截bean的创建。
现在来分析下到底是怎么注册bean的后置处理器的。
- 先安装类型拿到IOC容器中所有需要创建的后置处理器,即先获取IOC容器中已经定义了的需要创建对象的所有BeanPostProcessor。如下代码所示:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
那IOC容器中的已定义的BeanPostProcessor从哪里来呢?
在创建IOC容器是,需要先传入配置类,而我们在解析配置类的时候,由于这个配置类里面有个@EnableAspectJAutoProxy注解,该注解会在容器中注册一个AnnotationAwareAspectJAutoProxyCreator(后置处理器),这仅仅是@EnableAspectJAutoProxy注解做的事,除此之外,容器中还有一些默认的后置处理器的定义。
所以,程序运行到这,容器中已经有一些我们将要用的后置处理器定义了,只不过现在还没有创建这些后置处理器的bean实例。
- 继续往下看这个registerBeanPostProcessors()方法,可以看到它里面还有其他的逻辑,如下所示:
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
这是给beanFactory中添加一些其他的BeanPostProcessor,也就是说给容器中加别的BeanPostProcessor。
- 定位到了DefaultSingletonBeanRegistry类的getSingleton()方法
也就是说如果从IOC容器中第一次获取单实例的bean出现问题,也即获取不到时,那么就会调用singletonFactory的getObject()方法。
我们继续跟进方法调用栈,如下图所示,可以看到现在又定位到了AbstractBeanFactory抽象类的doGetBean()方法中。
可以发现,现在就是来创建bean了,也就是说如果获取不到就创建bean。实际上就是创建BeanPostProcessor对象,然后保存到容器中。
接着再跟进方法调用栈,如下图所示,可以看到现在是定位到了AbstractAutowireCapableBeanFactory抽象类的doCreateBean()方法中。
程序停留在这儿,就是在初始化bean实例,说明bean实例已经创建好了,如果你要不信的话,那么可以往前翻阅该doCreateBean()方法,这时你应该会看到一个createBeanInstance()方法,说的就是bean实例的创建。创建的是哪个bean实例呢?就是名称为internalAutoProxyCreator的实例,该实例的类型就是我们之前经常说的AnnotationAwareAspectJAutoProxyCreator,即创建这个类型的实例。创建好了之后,就在程序停留的地方进行初始化。
所以整个过程如下:
- 首先创建bean实现。
- 然后给bean的各种属性赋值。
- 接着初始化bean(即调用initializeBean()方法),这个初始化bean其实特别的重要,因为我们这个后置处理器就是在bean初始化前后进行工作的。
接下来,我们就来看看这个bean的实例是如何初始化的。继续跟进方法调用栈,如下图所示,可以看到现在是定位到了AbstractAutowireCapableBeanFactory抽象类的initializeBean()方法中。
初始化bean流程
- 首先进入invokeAwareMethods方法,如下图。
其实,这个方法是来判断我们这个bean对象是不是Aware接口的,如果是,并且它还是BeanNameAware、BeanClassLoaderAware以及BeanFactoryAware这几个Aware接口中的其中一个,那么就调用相关的Aware接口方法,即处理Aware接口的方法回调。
现在这个bean叫internalAutoProxyCreator,并且这个bean对象已经被创建了,创建出来的这个bean实现了BeanFactoryAware接口。 - 还是回到AbstractAutowireCapableBeanFactory抽象类的initializeBean()方法中。如果invokeAwareMethods()这个方法执行完了以后,那么后续又会发生什么呢?
往下翻阅initializeBean()方法,会发现有一个叫applyBeanPostProcessorsBeforeInitialization的方法,如下图所示。
这个方法调用完以后,会返回一个被包装的bean。
该方法的意思其实就是应用后置处理器的postProcessBeforeInitialization()方法。我们可以进入该方法中去看一看,到底是怎么应用后置处理器的postProcessBeforeInitialization()方法的?
可以看到,它是拿到所有的后置处理器,然后再调用后置处理器的postProcessBeforeInitialization()方法,也就是说bean初始化之前后置处理器的调用在这儿。
- 还是回到程序停留的地方,继续往下翻阅initializeBean()方法,你会发现还有一个叫invokeInitMethods的方法,即执行自定义的初始化方法。
这个自定义的初始化方法呢,你可以用@bean注解来定义,指定一下初始化方法是什么,销毁方法又是什么,这个我们之前都说过了。 - 自定义的初始化方法执行完以后,又有一个叫applyBeanPostProcessorsAfterInitialization的方法,该方法的意思其实就是应用后置处理器的postProcessAfterInitialization()方法。我们可以进入该方法中去看一看,到底是怎么应用后置处理器的postProcessAfterInitialization()方法的?
依旧是拿到所有的后置处理器,然后再调用后置处理器的postProcessAfterInitialization()方法。
所以,后置处理器的这两个postProcessBeforeInitialization()与postProcessAfterInitialization()方法前后的执行,就是在这块体现。
至此,整个这么一个流程下来以后,咱们的这个BeanPostProcessor,我们是以AnnotationAwareAspectJAutoProxyCreator(就是@EnableAspectJAutoProxy这个注解核心导入的BeanPostProcessor)为例来讲解的,就创建成功了。并且还调用了它的initBeanFactory()方法得到了一些什么aspectJAdvisorFactory和aspectJAdvisorsBuilder,这两个东东大家知道一下就行了。至此,整个initBeanFactory()方法我们就说完了,也就是说我们整个的后置处理器的注册以及创建过程就说完了。
总结
现在我们知道了registerBeanPostProcessors(beanFactory);其实就是拿到所有的BeanPostProcessor,然后调用beanFactory的addBeanPostProcessor方法将BeanPostProcessor注册到BeanFactory中。
总之,就是把容器中所有的后置处理器全部创建bean实例,然后把这些bean实例初始化,最后添加到BeanFacotry中。
参考
Spring注解驱动开发第28讲——为你呕心沥血分析创建和注册AnnotationAwareAspectJAutoProxyCreator的过程,这应该是全网分析的最详细的了!