流程图
代码
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {Set<String> processedBeans = new HashSet<>();// beanFactory 默认使用的是 DefaultListableBeanFactory,属于 BeanDefinitionRegistryif (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 接口的方法 :postProcessBeanDefinitionRegistryinvokeBeanDefinitionRegistryPostProcessors(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:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessorregularPostProcessors:记录通过硬编码方式注册的BeanFactoryPostProcessorregitstryPostProcessorBeans:记录通过配置方式注册的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,占位符与敏感信息解密原理
