流程图
代码
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
// beanFactory 默认使用的是 DefaultListableBeanFactory,属于 BeanDefinitionRegistry
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 两个后处理器列表
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 硬编码注册的后处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 分类处理
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 首先,调用实现 priorityOrder 的 beanDefinition 这就是前面提到过的优先级概念,这一步跟下面的优先级不一样之处,这一步的优先级是带有权重
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();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
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);
// 执行 definitionRegistryPostProcessor 接口的方法 :postProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.最后,调用所有其他后处理器,直到不再出现其他 bean 为止
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();
}
// 执行 postProcessBeanFactory 回调方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 不要在这里初始化 factoryBean:我们需要保留所有常规 bean 未初始化,以便让 bean 工厂后处理程序应用于它们
// 注释 6.4 在这个步骤中,我们自定义的 carBeanFactoryPostProcessor 才真正注册并执行
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);.
// 跳过分类的逻辑
// 首先执行的是带有权重顺序的后处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 下一步执行普通顺序的后处理器
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最后执行的是普通的后处理器
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除缓存的合并bean定义,因为后处理程序可能已经修改了原始元数据,例如替换值中的占位符
beanFactory.clearMetadataCache();
}
从上面贴的代码中能够看到,对于 beanFactoryPostProcessor
的处理主要分两种情况:
beanFactory
是BeanDefinitionRegistry
类型:需要特殊处理beanFactory
不是BeanDefinitionRegistry
类型:进行普通处理
对于每种情况都需要考虑硬编码注入注册的后处理器(上面已经提到如何进行硬编码)以及通过配置注入的后处理器
对于 BeanDefinitionRegistry
类型的处理器的处理主要包括以下内容:
- 处理硬编码注册的后处理器
- 记录后处理器主要使用以下三个
List
registryPostProcessors
:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor
regularPostProcessors
:记录通过硬编码方式注册的BeanFactoryPostProcessor
regitstryPostProcessorBeans
:记录通过配置方式注册的BeanDefinitionRegistryPostProcessor
- 对于以上后处理器列表,统一调用
BeanFactoryPostProcessor
的postProcessBeanFactory
方法 - 对
beanFactoryPostProcessors
中非BeanDefinitionRegistryPostProcessor
类型的后处理器进行统一的postProcessBeanFactory
方法 - 普通
beanFactory
处理:其实在这一步中,就是忽略了BeanDefinitionRegistryPostProcessor
类型,对BeanFactoryPostProcessor
进行直接处理。
流程图中描述了整体调用链路,具体调用方法在代码中的注释也描述出来了,所以结合起来看应该能够理解整体流程~
总结
本次分析了 beanFactory
的后处理器 BeanFactoryPostProcessor
,了解了 Spring
给我们提供的这个扩展接口使用用途和在源码中如何进行激活执行。
由于个人技术有限,如果有理解不到位或者错误的地方,请留下评论,我会根据朋友们的建议进行修正
代码和注释都在里面,小伙伴们可以下载我上传的代码,亲测可运行~
Gitee 地址:https://gitee.com/vip-augus/spring-analysis-note.git
Github 地址:https://github.com/Vip-Augus/spring-analysis-note
参考资料
- Bean 定义
- Sping 的 BeanFactory 容器
- Spring拓展接口之BeanFactoryPostProcessor,占位符与敏感信息解密原理