Spring 源码学习 11:invokeBeanFactoryPostProcessors
前言
invokeBeanFactoryPostProcessors 会执行 BeanFactory 的后置处理器。看到这里会有疑问:
- 什么是 BeanFactoryPostProcessor ?
- BeanfactoryPostProcessor 该如何使用?
知道了上面两个问题的答案,对 BeanFactoryPostProcessor 有了了解之后,然后再深入源码,继续阅读 invokeBeanFactoryPostProcessors 这个方法。
作用
资料还是在官网可以找到答案:
阅读了一下,大概意思是 Spring IoC 容器允许 BeanFactoryPostProcessor 读取配置元数据,并有可能在容器实例化除 BeanFactoryPostProcessor 实例以外的任何 bean 之前更改它。
同样可以使用 Ordered 接口对 BeanFactoryPostProcessor 进行排序。
注意
BeanFactoryPostProcessor 操作的是 BeanDefinition ,即元数据。但是同样可以通过获取到 BeanFactory 进行实例化 Bean,但是官网很不建议这样使用。
示例
使用 BeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 修改 BeanDefinition 信息
BeanDefinition userComponentBeanDefinition = beanFactory.getBeanDefinition("userComponent");
userComponentBeanDefinition.setLazyInit(true);
// 修改 Bean 的信息
// xxx 非常不推荐 beanFactory.getBean 过早的实例化 Bean
UserComponent bean = beanFactory.getBean(UserComponent.class);
bean.setUserName("liuzhihang-01");
}
}
创建自己的 BeanFactoryPostProcessor 并实现 BeanFactoryPostProcessor 接口,添加注解即可。
当然除了实现 BeanFactoryPostProcessor 接口,还有其他接口可以实现:
使用 BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor,同时扩展了增加了 postProcessBeanDefinitionRegistry
方法。可以支持在 BeanDefinition 注册之后 Bean 实例化之前对 BeanDefinition 进行操作。
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 修改 BeanDefinition 信息
BeanDefinition userComponentBeanDefinition = beanFactory.getBeanDefinition("userComponent");
userComponentBeanDefinition.setLazyInit(true);
// 修改 Bean 的信息
// xxx 非常不推荐 beanFactory.getBean 过早的实例化 Bean
UserComponent bean = beanFactory.getBean(UserComponent.class);
bean.setUserName("liuzhihang-01");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 注册一个 BeanDefinition
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OrderComponent.class);
AbstractBeanDefinition orderComponentBeanDefinition = builder.getBeanDefinition();
registry.registerBeanDefinition("orderComponent", orderComponentBeanDefinition);
}
}
下面是测试代码截图:
OrderComponent 类没有添加任何注解,然后注册为 BeanDefinition 之后,从容器中可以获取到 orderComponent。
如何修改字段属性
在 Spring 文档上说明,非常不建议在 BeanFactoryPostProcessor 中实例化 Bean,那这时候想修改 Bean 的信息,改如何操作?
其实可以通过获取到 MutablePropertyValues
后进行操作:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 修改 BeanDefinition 信息
BeanDefinition userComponentBeanDefinition = beanFactory.getBeanDefinition("userComponent");
userComponentBeanDefinition.setLazyInit(true);
MutablePropertyValues userComponentPropertyValues = userComponentBeanDefinition.getPropertyValues();
userComponentPropertyValues.addPropertyValue("userName", "liuzhihang-02");
// 修改 Bean 的信息
// xxx 非常不推荐 beanFactory.getBean 过早的实例化 Bean
// UserComponent bean = beanFactory.getBean(UserComponent.class);
// bean.setUserName("liuzhihang-01");
}
}
invokeBeanFactoryPostProcessors
看完前面,我想已经知道了 BeanFactoryPostProcessor 是做什么用的了,而这一步的主要作用就是实例化所有的 BeanFactoryPostProcessor。
进入源码:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
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 (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
其中 getBeanFactoryPostProcessors 方法获取的是自己添加的 BeanFactoryPostProcessor。这句话是什么意思呢?
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
看源码,就是直接从 beanFactoryPostProcessors 获取的,那如何向其中添加呢?
其实调用容器的 addBeanFactoryPostProcessor
方法即可。
继续阅读重点代码 invokeBeanFactoryPostProcessors
:
注意注意,这块代码非常长!
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 判断是否为 BeanDefinitionRegistry
// debug 发现 这里传入的是 DefaultListableBeanFactory
// DefaultListableBeanFactory 实现了 BeanDefinitionRegistry
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 创建了两个 List 集合, 用来存放处理器
// BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子接口
// BeanDefinitionRegistryPostProcessor 还可以额外处理 BeanDefinition, 添加 BeanDefinition
// 用法可以参考示例
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 循环 beanFactoryPostProcessors
// beanFactoryPostProcessors 是使用 API context.addBeanFactoryPostProcessor 添加进来的
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// BeanDefinitionRegistryPostProcessor 要单独添加到 registryProcessors
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 处理 Bean 的信息
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 上面循环是执行的我们调用 API 添加的 BeanDefinitionRegistryPostProcessor
// 下面执行 Spring 自己的 BeanDefinitionRegistryPostProcessor 集合
// 先执行实现了 PriorityOrdered接口的,然后是 Ordered 接口的,最后执行剩下的
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 第一步先调用 BeanDefinitionRegistryPostProcessors 它实现了PriorityOrdered
// 在初始化 reader 时 在注册了 ConfigurationClassPostProcessor 到容器里面
// BeanDefinitionRegistryPostProcessor 实现了 BeanDefinitionRegistryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 添加 bean
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 这里只添加了名字 后面用来判断谁已经执行过了
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 循环执行 processors 的 postProcessBeanDefinitionRegistry 方法
// 这个得在仔细看
// debug 看到 执行完这一步我另一个加 @Component 注解的类 注册到 Registry 里面了
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
// 清除
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 处理实现 Ordered 的 processor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 只有不包含的才执行, 执行完之后会添加进 processedBeans
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后执行其他
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 只有不包含的才执行, 执行完之后会添加进 processedBeans
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 上面处理的都是 postProcessBeanDefinitionRegistry 是在 -> BeanDefinitionRegistryPostProcessor 中
// 下面开始处理 postProcessBeanFactory -> 是在 BeanFactoryPostProcessor 中
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
// 不是 BeanDefinitionRegistry 则是普通 BeanFactory 直接执行 beanFactoryPostProcessors 即可
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 第二部分
// 上面执行的是 BeanDefinitionRegistryPostProcessor
// 下面开始执行 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 按照顺序执行
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
// 说明上面已经执行了, 下面忽略
} 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);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 执行实现 PriorityOrdered 的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 清空不必要的元数据信息
beanFactory.clearMetadataCache();
}
上面总体可以分为两部分:
- 执行 BeanDefinitionRegistryPostProcessor 接口里面的两个方法:postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
- 执行 BeanFactoryPostProcessor 接口里面的 postProcessBeanFactory 方法。
以第一部分为例:
- 首先判断传入的 BeanFactory 是否为 BeanDefinitionRegistry
- 声明两个 List 集合,regularPostProcessors 用来存储 BeanFactoryPostProcessor,registryProcessors 用来存储 BeanDefinitionRegistryPostProcessor
- 循环 beanFactoryPostProcessors,这个就是我们使用 API 方式添加进来的 BeanFactoryPostProcessor。
- 在循环中 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 会被执行,也就是说我示例的那个添加 BeanDefinition 演示的方法会被执行。
- 开始执行 Spring 自己的 BeanDefinitionRegistryPostProcessor, 处理顺序为 PriorityOrdered, Ordered, and the rest
- 循环,将对应的 BeanDefinitionRegistryPostProcessor 添加到 currentRegistryProcessors 集合和processedBeans集合表示为已经处理。
- 排序后添加到第一步的 registryProcessors 中。
- 调用 invokeBeanDefinitionRegistryPostProcessors 执行所有的 Processor 里面的 postProcessBeanDefinitionRegistry 方法
- 执行完 1 和 2 之后,所有的 postProcessBeanDefinitionRegistry 已经被执行完了,但是两个集合(registryProcessors、regularPostProcessors)里面的 postProcessBeanFactory 方法还没有被执行。最后会循环执行。
- 声明两个 List 集合,regularPostProcessors 用来存储 BeanFactoryPostProcessor,registryProcessors 用来存储 BeanDefinitionRegistryPostProcessor
- 如果不是 BeanDefinitionRegistry 类型,则直接执行传入的 beanFactoryPostProcessors 即可。
下面是对应的代码截图
以上只是这个方法的前半部分,执行了 BeanDefinitionRegistryPostProcessor 里面的 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
因为还有直接实现 BeanFactoryPostProcessor 的处理器,下面则开始处理 BeanFactoryPostProcessor 的处理器。过程和上面类似。
总结
通过以上的阅读,对 invokeBeanFactoryPostProcessors(beanFactory);
这一步方法进行总结。
BeanFactoryPostProcessor 作用
BeanFactoryPostProcessor 主要作用是在注册 BeanDefinition 之后,在 Bean 初始化之前,修改 BeanDefinition 的信息。
BeanFactoryPostProcessor 有个实现叫 BeanDefinitionRegistryPostProcessor,它可以额外的注册新的 BeanDefinition 到容器中。
流程概述
- 这一步主要是处理 BeanFactoryPostProcessor,分为两步。
- 执行 BeanDefinitionRegistryPostProcessor 接口里面的两个方法:postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
- 执行 BeanFactoryPostProcessor 接口里面的 postProcessBeanFactory 方法。