抄录于 https://blog.csdn.net/m0_45406092/article/details/114847361
【spring源码】Spring IoC源码学习:invokeBeanFactoryPostProcessors() 详解
相关文章:
Spring源码系列之容器启动流程 建议先阅读这篇文章
系列文章:
【spring源码】01.Spring源码整体脉络介绍及源码编译–spring笔记
【spring源码】02.Ioc容器加载过程-Bean的生命周期源码深度剖析–spring笔记
【spring源码】Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解
【spring源码 4.3.7】ConfigurationClassPostProcessor
【spring源码 4.3.7】Spring IoC源码学习:registerBeanPostProcessors() 详解
【spring源码 4.3.7】Spring IoC源码学习:finishBeanFactoryInitialization() 详解
【spring源码 4.3.7】Spring IoC源码学习:BeanFactory.getBean() 详解
【spring源码 4.3.7】Spring IoC源码学习:AbstractAutowireCapableBeanFactory.populateBean()
【spring源码 4.3.7】Spring IoC源码学习:AbstractAutowireCapableBeanFactory.initializeBean() 初始化生命周期
前言
bean实例化的周期图:
-
在实例化bean之前,也会有个
BeanFactoryPostProcessor接口实例的链式集合,用于处理bean定义; -
bean的定义固化下来后,就进行new 实例化的操作
-
在new 的过程中,就会有很多步骤,例如实现了Aware接口实例的一组集合,类似链式,逐一处理一遍,接着是实现了
BeanPostProcessor接口实例的一组集合,类似链式,逐一处理一遍重点来了,这个预置的处理链时是怎么生成的?答案就是 在一个项目启动时,会预先加载一些bean定义,这些bean根据类型,会加入不同的处理链,而【spring注解】context:annotation-config和context:component-scan区别 内的 context:annotation-config和context:component-scan语法就是在其定义的范围内的,如果实现了BeanFactoryPostProcessor和BeanPostProcessor,这些bean 就被当做处理器,加入集合。BeanFactoryPostProcessor处理器链的加载过程就是本篇文章的目的
概述
* * * * BeanFactoryPostProcessor接口的唯一内置实现类是ConfigurationClassPostProcessor,详情参见 【spring源码 4.3.7】ConfigurationClassPostProcessor,并且这个类的优先级是最高的,在invokeBeanFactoryPostProcessors()方法中优先执行。
整体的流程图:
本方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor,子类优先级高,会优先处理)。
BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。
BeanFactoryPostProcessor 详细用法参见《Spring的BeanFactoryPostProcessor和BeanPostProcessor》
BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor接口(比 BeanFactoryPostProcessor 具有更高的优先级执行),那么一定要做些事情,子接口前缀BeanDefinitionRegistry顾名思义,负责BeanDefinition的注册,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。
特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。
注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。
因此,invokeBeanFactoryPostProcessors()主要功能就是寻找实现BeanFactoryPostProcessor的子类,并调用他们的重载方法,比如子类BeanDefinitionRegistryPostProcessor 负责注册bean(仅仅是注册,不是实例化,但是也需要提前实例化一部分bean)。
1. invokeBeanFactoryPostProcessors
首先我们回到 AbstractApplicationContext.refresh() 方法,找到代码:invokeBeanFactoryPostProcessors(beanFactory) ,单击该行代码跳转到具体的实现。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 【1】.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
// 【2】.invokeBeanFactoryPostProcessors(): 实例化并调用所有已注册的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
【1】.拿到当前应用上下文 beanFactoryPostProcessors 变量中的值,见代码块1详解。
【2】.实例化并调用所有已注册的 BeanFactoryPostProcessor,见代码块2详解。
1.1 代码块1:getBeanFactoryPostProcessors()
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
//成员变量,List<BeanFactoryPostProcessor>结构的集合
return this.beanFactoryPostProcessors;
}
- 1
- 2
- 3
- 4
这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors ()是返回空的。
如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量中了?
如果还有印象的话,我们在 Spring IoC:refresh前的环境准备 中的代码块12介绍过 customizeContext 方法,该方法是 Spring 提供给开发者的一个扩展点,用于自定义应用上下文,并且在 refresh() 方法前就被调用。在这边就可以通过该方法来添加自定义的 BeanFactoryPostProcessor。
简单来说,内置的BeanFactoryPostProcessor实现类或者定义@Component(等待spring扫描的实现了BeanFactoryPostProcessor接口的)的实现类,不在 this.beanFactoryPostProcessors 变量中,该变量存储的是其他方式定义的BeanFactoryPostProcessor。
这种其他方式定义的BeanFactoryPostProcessor实现类使用方式如下:
1.新建一个 ApplicationContextInitializer 的实现类 MySpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑。
package com.joonwhee.open.demo.spring;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author joonwhee
* @date 2019/1/19
*/
public class MySpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
// 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
// ...自定义操作
System.out.println("SpringApplicationContextInitializer#initialize");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
2.将 MySpringApplicationContextInitializer 作为初始化参数 contextInitializerClasses 配置到 web.xml 中。
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>
com.joonwhee.open.demo.spring.MySpringApplicationContextInitializer
</param-value>
</context-param>
- 1
- 2
- 3
- 4
- 5
- 6
这样,在启动应用时,FirstBeanDefinitionRegistryPostProcessor 就会被添加到 this.beanFactoryPostProcessors集合 中。
1.2 代码块2:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
搜索【2】处代码
总体流程图:
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 定义已经处理完成的Bean的集合,当后处理完成后,加入该集合里面
Set<String> processedBeans = new HashSet<>();
//[1]beanFactory是DefaultListableBeanFactory,是BeanDefinitionRegistry的实现类,所以肯定满足if
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//regularPostProcessors 专门用来存放扩展父接口BeanFactoryPostProcessor的实现类(但是与其子类BeanDefinitionRegistryPostProcessor区分开)
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors 专门用来存放子类BeanDefinitionRegistryPostProcessor
//子类BeanDefinitionRegistryPostProcessor也扩展了BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 可以先跳过:
// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
// 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
// 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//如过是BeanDefinitionRegistryPostProcessor的话,调用其方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到BeanDefinitionRegistryPostProcessor集合
registryProcessors.add(registryProcessor);
}
else {
//添加到普通的集合,非BeanDefinitionRegistryPostProcessor实现的子类
regularPostProcessors.add(postProcessor);
}
}
//一个临时变量,用来装载子类BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
// 3.1 先找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 3.2 遍历postProcessorNames,进行过滤
for (String ppName : postProcessorNames) {
// 3.3 校验是否实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中
//其实就是内置的bean的名称org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// beanFactory.getBean(): 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//3.5 将要被执行的加入processedBeans,避免后续重复执行
processedBeans.add(ppName);
}
}
// 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
//3.7 合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
//一开始的时候,spring只会执行子类BeanDefinitionRegistryPostProcessor独有的方法
//而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
//所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
registryProcessors.addAll(currentRegistryProcessors);
//3.8 遍历currentRegistryProcessors, 执行子类BeanDefinitionRegistryPostProcessor独有的方法postProcessBeanDefinitionRegistry()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3.9 执行完毕后,清空临时变量
currentRegistryProcessors.clear();
// 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
// 4.1 先找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
// 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//校验是否实现了Ordered接口,与步骤3相比,有个细微区别,就是!processedBeans.contains(ppName)避免重复步骤3已经处理过的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//也是实例化bean
currentRegistryProcessors.add(beanFactory.getBean


