五、bean工厂后置处理器
5.1、源码解析
refresh()方法比较重要的代码是上篇文章标注的第5条和第11条代码,本次先解析第5行的代码invokeBeanFactoryPostProcessors,执行bean工厂后置处理器。
点进invokeBeanFactoryPostProcessors,
再点进PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
代码逻辑比较复杂,解析如下:
5.2、后置处理器-BeanFactotyPostProcessor
5.2.1、概念
Spring中有两种后置处理器,分别为BeanFactotyPostProcessor和BeanPostProcessor。前者叫bean工厂后置处理器,后者叫bean后置处理器。
后置处理器体现了Spring框架的设计的开闭原则,我们可以通过Spring提供的一些接口,参与到Spring的上下文容器的创建过程中。
Spring框架本身已经提供了众多的后置处理器,每种处理器都有不同的作用。我们也可以自己定义后置处理器,编写自己需要的逻辑,参与到上下文ApplicationContext和bean的创建过程中。
5.2.2、BeanFactoryPostProcessor
BeanFactoryPostProcessor接口是位于spring-beans项目的org.springframework.beans.factory.config.BeanFactoryPostProcessor。
1)作用
通过BeanFactoryProcessor接口可以干预Spring的BeanFactory的创建过程中。
2)API
BeanFactoryPostProcessor中只有一个抽象方法:
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
Spring在bean工厂创建、BeanDefinition注册完成之后,会回调这个接口的所有已经注册了BeanDefinition的实现子类,传入bean工厂。
3)使用
我们可以写代码实现这个接口,然后将这个实现类放入spring容器中或者调用容器的addBeanFactoryPostProcessor方法交给容器。这样我们就可以拿到spring的beanFactory了,完成自己对于bean工厂处理的逻辑。
一般情况我们拿到工厂后就可以拿到工厂中所有的BeanDefinition(beanDefinitionMap)了,这个时候bean还没有进行实例化,我们可以修改BeanDefinition完成自己的需要的逻辑处理。
我们也可以在这个地方通过beanFactory的addBeanPostProcessor方法注入自己的BeanPostProcessor后置处理器。
5.2.3、BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor接口是BeanFactoryPostProcessor接口的子接口。
1)作用
通过这个子接口我们可以向Spring容器中注入BeanDefinition。
2)API
BeanDefinitionRegistryPostProcessor中只有一个抽象方法:
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
Spring在执行BeanFactoryPostProcessor后置处理器之前,会先执行BeanDefinitionRegistryPostProcessor后置处理器中的postProcessBeanDefinitionRegistry方法。这个方法会传入registry注册器。
3)使用
我们可以写代码实现这个接口,然后将这个实现类放入spring容器中或者调用容器的addBeanFactoryPostProcessor方法交给容器。
有了registry,我们就可以向spring容器中放入各种BeanDefinition,比如加入普通BeanDefinition、BeanFactoryPostPorcessor、BeanPostProcessor、甚至是自己BeanDefinitionRegistryPostProcessor。
5.2.4、BeanFactotyPostProcessor的执行顺序
Spring会先调用BeanDefinitionRegistryPostProcessor,然后再调用BeanPostProcessor。
该图中的序号对应源码解析截图中的序号。
5.2、ConfigurationClassPostProcessor
5.2.1、ConfigurationClassPostProcessor注册时机
ConfigurationClassPostProcessor是BeanDefinitionRegistryPostProcessor的实现类。也是spring中最重要的一个bean工厂后置处理器。
这个类完成了
ConfigurationClassPostProcessor什么时候加入到的spring bean工厂的beanDefinitionMap中的呢?
我们回到AnnotationConfigApplicationContext的无参构造方法中。
我们点开AnnotatedBeanDefinitionReader的构造方法。
继续,
注意这个代码的最后一行,调用了AnnotationConfigUtils的registerAnnotationConfigProcessors方法,并将registry传进去了,这个registry就是我们的annotationConfigApplicationContext对象,我们继续点进去。
继续,
原来是在这里注册了一堆bd,里面有我们需要关注的bd:ConfigurationClassPostProcessor。
因为ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,通过我们上述代码的解析,我们知道,肯定会执行到这个类中的代码,我们来看下这个类究竟做了什么。
5.2.2、postProcessBeanDefinitionRegistry
首先会执行这个类的postProcessBeanDefinitionRegistry方法:
这个方法主要逻辑在processConfigBeanDefinitions方法,点开:
源码解析: