我们先通过Spring的BeanFactoryPostProcessor的流程图,来了解Spring的BeanFactoryPostProcessor 的工作流程是什么,接着根据这个工作流程一步一步的阅读源码 
一、前言
文章目录:Spring源码分析:文章目录
本文分析的方法是 AbstractApplicationContext#invokeBeanFactoryPostProcessors方法
PS : 个人感觉,实现IOC的两个核心后处理器 :
ConfigurationClassPostProcessor 解析配置类(这里的配置类不仅仅局限于 @Configuration 注解,还包括 @Import 、 @ImportResource 等注解),将解析到的需要注入到Spring容器中的bean的 BeanDefinition 保存起来AutowiredAnnotationBeanPostProcessor 解析bean中的 需要自动注入的bean @Autowired 和 @Inject @Value 注解。
二、BeanFactoryPostProcessor & BeanDefinitionRegistryPostProcessor
由于invokeBeanFactoryPostProcessors 方法中主要就是对BeanFactoryPostProcessor 的处理,所以这里简单的介绍一下 BeanFactoryPostProcessor 及其子接口 BeanDefinitionRegistryPostProcessor 。其结构如下图: 
BeanFactoryPostProcessor概述: BeanFactoryPostProcessor 接口定义了 BeanFactory 的后置处理器接口,该接口可以改变已经定义在 BeanFactory 中已注册Bean的信息(比如参数),Spring 在完成上下文实例化之前,允许我们通过 BeanFactoryPostProcessor 来对 BeanFactory 中已注册的Bean进行修改,从而得实例化到我们预期想要的Bean,这种方式兼顾了扩展性,也是 Spring 强大灵活,扩展性高的部分原因。
BeanFactoryPostProcessor 相比较于 BeanPostProcessor 方法是很简单的,只有一个方法,其子接口也就一个方法。但是他们俩的功能又是类似的,区别就是作用域并不相同。BeanFactoryPostProcessor 的作用域范围是容器级别的。它只和你使用的容器有关。如果你在容器中定义一个BeanFactoryPostProcessor ,它仅仅对此容器中的bean进行后置处理。BeanFactoryPostProcessor 不会对定义在另一个容器中的bean进行后置处理,即使这两个容器都在同一容器中。BeanFactoryPostProcessor 可以对 bean的定义(配置元数据)进行处理。Spring IOC 容器允许 BeanFactoryPostProcessor 在容器实际实例化任何其他bean之前读取配置元数据,并有可能修改它,也即是说 BeanFactoryPostProcessor 是直接修改了bean的定义,BeanPostProcessor 则是对bean创建过程中进行干涉。
BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 的区别在于:
-
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry() 方法针对是BeanDefinitionRegistry 类型的ConfigurableListableBeanFactory ,可以实现对BeanDefinition 的增删改查等操作,但是对于非 ConfigurableListableBeanFactory 类型的BeanFactory ,并不起作用。 -
BeanFactoryPostProcessor#postProcessBeanFactory() 针对的是所有的BeanFactory 。 -
postProcessBeanDefinitionRegistry 的调用时机在postProcessBeanFactory 之前。
三、代码分析
1、BeanFactory
BeanFactoryPostProcessor 接口定义了postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法,该方法作用是在BeanFactory 实例化Bean之前,对其中的BeanDefinition 进行修改参数等一系列操作,入参是一个 BeanFactory ,但是从我们之前的学习当中我们知道Spring中的 BeanFactory 其实是一个叫DefaultListableBeanFactory 类型的BeanFactory ,那么入参当中的ConfigurableListableBeanFactory 和DefaultListableBeanFactory 为什么关系呢?我们来通过下面提到的DefaultListableBeanFactory 的继承关系图。我们看到 DefaultListableBeanFactory 实现了ConfigurableListableBeanFactory 。这一点在 Spring源码深度解析:三、容器的刷新 - refresh()中已经得到证实。
下面我们看看 DefaultListableBeanFactory 的结构图如下,可以看到DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口。这点在下面的分析中会用到。 
2、代码分析
invokeBeanFactoryPostProcessors 方法的作用是激活BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor 。
为了更好的了解下面的代码,我们先了解几个代码中的规则:
-
BeanFactoryPostProcessor 在本次分析中分为两种类型: BeanFactoryPostProcessor 和其子接口 BeanDefinitionRegistryPostProcessor 。BeanDefinitionRegistryPostProcessor 相较于 BeanFactoryPostProcessor ,增加了一个方法如下。  需要注意的是,BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 这个方法仅仅针对于 BeanDefinitionRegistry 类型的BeanFactory 生效,这一点根据其入参就可以看到。 总结一下即 :BeanFactoryPostProcessor 针对所有的 BeanFactory ,即对于所有类型的BeanFactory 都会调用其方法;BeanDefinitionRegistryPostProcessor 仅对 BeanDefinitionRegistry 子类的BeanFactory 起作用,非BeanDefinitionRegistry 类型则直接处理即可。 -
BeanFactoryPostProcessor 的注入分为两种方式: 1、配置注入方式:即通过注解或者xml的方式动态的注入到容器中的BeanFactoryPostProcessor 2、硬编码注入方式: 这种方式是直接调用 AbstractApplicationContext#addBeanFactoryPostProcessor 方法将 BeanFactoryPostProcessor 添加到 AbstractApplicationContext.beanFactoryPostProcessors 属性中。其中硬编码注入的BeanFactoryPostProcessor 并不需要也不支持接口排序,而配置注入的方式因为Spring无法保证加载的顺序,所以通过支持PriorityOrdered、Ordered 排序接口的排序。 -
在下面代码分析中会有四个集合 1、regularPostProcessors : 记录通过硬编码方式注册的BeanFactoryPostProcessor 类型的处理器 2、registryProcessors :记录所有的BeanDefinitionRegistryPostProcessor 类型的处理器 3、currentRegistryProcessors : 一个临时集合变量,记录通过配置方式注册的BeanDefinitionRegistryPostProcessor 类型的处理器 4、processedBeans :记录当前记录所有即将或已经处理的beanName(包含:BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor ),用于防止重复处理
其实调用顺序可以归纳为:1)、硬编码先于配置;2)、postProcessBeanDefinitionRegistry 先于postProcessBeanFactory
下面我们来看具体代码: AbstractApplicationContext#invokeBeanFactoryPostProcessors() 方法内容如下
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
可以看到主要功能还是在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 这一句上。我们先来看看 getBeanFactoryPostProcessors() 得到的是什么
2.1、getBeanFactoryPostProcessors()
AbstractApplicationContext类
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
@Override
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
可以看到 getBeanFactoryPostProcessors() 方法仅仅是将 beanFactoryPostProcessors 集合返回了出去而已。那么 beanFactoryPostProcessors 集合是通过 add方法添加的。这就是我们上面提到过的,beanFactoryPostProcessors 实际上是硬编码形式注册的BeanDefinitionRegistryPostProcessor 类型的处理器集合。
2.2、invokeBeanFactoryPostProcessors
通过上一步,我们可以知道 入参中的beanFactoryPostProcessors 集合是硬编码注册的 集合。对于下面的分析我们就好理解了。
下面代码主要是对于BeanDefinitionRegistry 类型 BeanFactory 的处理以及 BeanFactoryPostProcessor 调用顺序问题的处理。实际上并不复杂。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
}
这里的主要流程:
-
首先执行我们自定义通过AbstractApplicationContext.addBeanFactoryPostProcessor 方法添加进来的BeanFactory 后置处理器,然后调用这些beanFactory 后置处理器的postProcessBeanDefinitionRegistry 方法,并按类型分装到集合,方便后续统一调用父类BeanFactoryPostProcessor 类型的postProcessBeanFactory 方法 -
获取配置方式注册的所有BeanDefinitionRegistryPostProcessor 类型的beanFactory 后置处理器,遍历出实现了PriorityOrdered 接口的beanFactory 后置处理器,进行排序,放到临时存储集合中,然后调用这些 beanFactory 后置处理器的postProcessBeanDefinitionRegistry 方法; -
获取配置方式注册的所有 BeanDefinitionRegistryPostProcessor 类型的beanFactory 后置处理器,遍历出实现了Ordered 接口的beanFactory 后置处理器,进行排序,放到临时存储集合中,然后调用这些beanFactory 后置处理器的 postProcessBeanDefinitionRegistry 方法; -
获取配置方式注册的所有BeanDefinitionRegistryPostProcessor 类型的beanFactory 后置处理器,遍历出既不实现 PriorityOrdered 接口又不实现Ordered 接口的beanFactory 后置处理器,放到临时存储集合中,然后调用这些 beanFactory 后置处理器的postProcessBeanDefinitionRegistry 方法; -
执行前三步放入临时集合当中配置方式注册的所有BeanDefinitionRegistryPostProcessor 类型的beanFactory 后置处理器的父类BeanFactoryPostProcessor 中的postProcessBeanFactory 方法,将前三步中处理的beanFactory 后置处理器放到一个临时集合中也是为了这一步操作考虑; -
执行硬编码注入的beanFactory 后置处理器BeanFactoryPostProcessor 中的postProcessBeanFactory 方法 -
获取获取配置方式注册的所有BeanFactoryPostProcessor 类型的beanFactory 后置处理器,遍历出实现了PriorityOrdered 接口的beanFactory 后置处理器,进行排序,然后调用这些beanFactory 后置处理器的postProcessBeanFactory 方法; -
获取获取配置方式注册的所有BeanFactoryPostProcessor 类型的beanFactory 后置处理器,遍历出实现了Ordered 接口的beanFactory 后置处理器,进行排序,然后调用这些beanFactory 后置处理器的 postProcessBeanFactory 方法; -
获取获取配置方式注册的所有BeanFactoryPostProcessor 类型的beanFactory 后置处理器,遍历出既不实现 PriorityOrdered 接口又不实现Ordered 接口的beanFactory 后置处理器,然后调用这些 beanFactory 后置处理器的postProcessBeanFactory 方法;
到这里,所有的BeanFactory 后置处理器就执行完毕了,这里通过分析源码,我们知道了一个BeanFactoryPostProcessor 的子类BeanDefinitionRegistryPostProcessor
四、模拟测试

- 首先我们创建两个Bean(
MyBeanDefinitionRegistryBean 和 MyRegularPostProcessorBean )
package com.wts.BeanFactoryPostProcessorTest;
public class MyBeanDefinitionRegistryBean {
private String desc = "Hello World";
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public void method(){
System.out.println("MyBeanDefinitionRegistry-method():" + desc);
}
public MyBeanDefinitionRegistryBean() {
System.out.println("我是BeanDefinitionRegistry");
}
}
public class MyRegularPostProcessorBean {
private String desc = "Hello World";
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public void method(){
System.out.println("MyRegularPostProcessorBean-method():" + desc);
}
}
- 创建Spring配置类:
SpringBeanConfig
@Configuration
@ComponentScan("com.wts.BeanFactoryPostProcessorTest")
public class SpringBeanConfig {
@Bean("myRegularPostProcessorBean")
public MyRegularPostProcessorBean getMyRegularPostProcessorBean(){
return new MyRegularPostProcessorBean();
}
}
- 创建一个我们自定义的
BeanDefinitionRegistryPostProcessor 和一个我们自定义的BeanFactoryPostProcessor
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("BDRPP.postProcessBeanDefinitionRegistry----start");
RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBeanDefinitionRegistryBean.class);
registry.registerBeanDefinition("myBeanDefinitionRegistryBean", beanDefinition);
System.out.println("BDRPP.postProcessBeanDefinitionRegistry----end");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BDRPP.postProcessBeanFactory----start");
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myBeanDefinitionRegistryBean");
MutablePropertyValues pv = beanDefinition.getPropertyValues();
pv.addPropertyValue("desc","Hello! My name is myBeanDefinitionRegistryBean, I was modified by the BDRPP.BeanFactoryPostProcessor");
System.out.println("BDRPP.postProcessBeanFactory----end");
}
}
@Component
public class MyBeanFactoryPostProcessors implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("BFPP.postProcessBeanFactory----start");
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myRegularPostProcessorBean");
MutablePropertyValues pv = beanDefinition.getPropertyValues();
pv.addPropertyValue("desc","Hello! My name is myBeanDefinitionRegistryBean, I was modified by the BFPP.BeanFactoryPostProcessor");
System.out.println("BFPP.postProcessBeanFactory----end");
}
}
- 创建测试类
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringBeanConfig.class);
MyRegularPostProcessorBean regularPostProcessor = (MyRegularPostProcessorBean)applicationContext.getBean("myRegularPostProcessorBean");
MyBeanDefinitionRegistryBean beanDefinitionRegistry = (MyBeanDefinitionRegistryBean)applicationContext.getBean("myBeanDefinitionRegistryBean");
regularPostProcessor.method();
System.out.println("----------------------------------------");
beanDefinitionRegistry.method();
}
}
- 结果:
 执行结果,可以看到打印出的文本已经不是我们一开始的 Hello World,而是被我们修改成了相应的内容,并且打印的文本和我们分析的主要流程一致。 到此,BeanFactoryPostProcessor 和BeanDefinitionRegistryPostProcessor 的解析和使用就已经完成了。
以上:内容部分参考 《Spring源码深度解析》 如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正
|