Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors()
2022/1/9 14:34:04
本文主要是介绍Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors(),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
# Spring
源码 - 容器刷新#invokeBeanFactoryPostProcessors()
Spring版本:Spring 5.3.13-release
# 1、invokeBeanFactoryPostProcessors()
将工厂的处理器作为Bean
激活到IOC
容器中
这一步的作用是调用各种BeanFactory
的增强处理器。其中最为关键的就是ConfigurationClassPostProcessor
,这个增强处理器完成了对配置类的解析,将解析得到将要注册的Bean
的BeanDefinition
。
AbstractApplicationContext#invokeBeanFactoryPostProcessors()
代码:
/** * 根据顺序, 实例化并注册所有的 BeanFactoryPostProcessor Bean 实例 * * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // getBeanFactoryPostProcessors() 直接返回通过硬编码形式注册的 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) // 通过类加载器织入, loadTimeWeaver (LOAD_TIME_WEAVER_BEAN_NAME) if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
主要注册BeanFactoryPostProcessor
的代码就是:
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
先看看getBeanFactoryPostProcessors()
得到的是什么,AbstractAplicationContext#getBeanFactoryPostProcessors()
代码:
@Override public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) { Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null"); this.beanFactoryPostProcessors.add(postProcessor); } /** * 返回通过 addBeanFactoryPostProcessor() 方法添加的用于内部 BeanFactory 的 BeanFactoryPostProcessor 集合 * @see AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor) * * Return the list of BeanFactoryPostProcessors that will get applied * to the internal BeanFactory. */ public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { // 直接返回 BeanFactoryPostProcessor return this.beanFactoryPostProcessors; }
可以看到getBeanFactoryPostProcessors()
就是直接返回用于内部BeanFactory
的BeanFactoryPostProcessor
集合。
那么这一句就很简单了,此处传递的参数就是内部BeanFactory
和所有作用于内部BeanFactory
的BeanFactoryPostProcessor
:
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
# 2、BeanFactory
的增强处理器
在看invokeBeanFactoryPostProcessors()
具体实现的代码之前,先说一下BeanFactory
的增强处理器:
# 1、BeanFactoryPostProcessor
接口
BeanFactoryPostProcessor
代码:
@FunctionalInterface public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
Modify the application context's internal bean factory after its standard initialization. All bean definitions will have been loaded, but no beans will have been instantiated yet.
从官方给出的接口注释中可以看出:
- 可以在容器中的内部
BeanFactory
在进行标准初始化之后对其进行修改。此时所有的BeanDefintion
已经全部加载完毕,但是Bean
还没开始实例化。
所以Spring
官方在注释文档中已经非常明确的说明了这个接口的用处:
- 在所有的
BeanDefintion
加载完成之后,Bean
进行实例化之前,对BeanDefintion
做一些定制化操作,比如说修改某个Bean
的BeanDefinition
。
# 2、BeanDefintionRegistryPostProcessor
接口:
BeanDefinitionRegistryPostProcessor
代码:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
可以看到BeanDefinitionRegistryPostProcessor
是BeanFactoryPostProcessor
子接口,所以看看类图先:
Modify the application context's internal bean definition registry after its standard initialization. All regular bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for adding further bean definitions before the next post-processing phase kicks in.
从官方给出的接口注释中可以看出:
- 可以在容器中的内部
BeanFactory
在进行标准初始化之后对其进行修改。此时所有常规的BeanDefinition
已经全部加载完毕,但是Bean
还没开始实例化。这允许在下一个Psot Processing
阶段之前继续添加Bean
的BeanDefintion
。
所以Spring
官方在注释文档中已经非常明确的说明了这个接口的用处:
- 在所有的常规
BeanDefintion
加载完成之后,Bean
进行实例化之前,下一个Post Processing
阶段之前继续添加Bean
的BeanDefintion
。
# 3、BeanDefinitionRegistryPostProcessor
& BeanFactoryPostProcessor
接口执行顺序
由此也可以推断出BeanDefinitionRegistryPostProcessor
接口和BeanFactoryPostProcessor
接口的执行顺序,BeanDefinitionRegistryPostProcessor
必然是优先于BeanFactoryPostProcessor
执行的。官方注释文档已经说的非常清楚了,BeanFactoryPostProcessor
是所有BeanDefintion
加载完毕Bean
实例化之前。
# 4、BeanFactoryPostProcessor
注入方式
BeanFactoryPostProcessor
接口的注入方式有两种:
- 配置注入:通过
XML
配置文件或者配置类的方式动态注入到容器中。 - 硬编码注入:直接调用
AbstractApplicationContext#addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)
方法将需要注入的BeanFactoryPostProcessor
添加到AbstractApplicationContext#beanFactoryPostProcessors
集合中。
通过硬编码注入的BeanFactoryPostPrcoessor
并不需要同时也不支持接口排序,因为在添加时就是有先后顺序的。而通过上述配置注入的,因为Spring
无法保证加载的先后顺序,所以通过配置注入的BeanFactoryPostProcessor
支持PriorityOrdered
、Ordered
排序接口的排序。
3、invokeBeanFactoryPostProcessors()
的具体实现
通过上面的描述,已经知道了:
-
BeanDefinitionRegistryPostProcessor
为BeanFactoryPostProcessor
子接口。BeanDefinitionRegistryPostProcessor
子接口中需要BeanDefinitionRegistry
类型的BeanFactory
,非BeanDefinitionRegistry
类型的BeanFactory
交由BeanFactoryPostProcessor
父接口进行激活。 -
BeanFactoryPostProcessor
的注入方式分为配置与硬编码两种。同时配置注入支持接口排序,而硬编码注入是不需要接口排序的。
接下来的源码,Spring
就是围绕上面的两点进行BeanFactoryPostProcessor
的具体激活代码实现。
invokeBeanFactoryPostProcessors()
的具体实现是PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
方法。
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // WARNING: Although it may appear that the body of this method can be easily // refactored to avoid the use of multiple loops and multiple lists, the use // of multiple lists and multiple passes over the names of processors is // intentional. We must ensure that we honor the contracts for PriorityOrdered // and Ordered processors. Specifically, we must NOT cause processors to be // instantiated (via getBean() invocations) or registered in the ApplicationContext // in the wrong order. // // Before submitting a pull request (PR) to change this method, please review the // list of all declined PRs involving changes to PostProcessorRegistrationDelegate // to ensure that your proposal does not result in a breaking change: // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22 // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); // 对于 BeanDefinitionRegistry 类型的处理, 这里是交由 BeanDefinitionRegistryPostProcessor 来处理 // 判断 BeanFactory 的类型, 如果是 BeanDefinitionRegistry 的子类, // 则交由 BeanDefinitionRegistryPostProcessor 处理, 否则直接按照 BeanFactoryPostProcessor 进行处理 // 由于 BeanDefinitionRegistryPostProcessor 只能处理 BeanDefinitionRegistry 的子类, 所以这里必须先进行 beanFactory 的区分 if (beanFactory instanceof BeanDefinitionRegistry) { // 以下逻辑看似复杂其实大体就是两步 // 1.获取所有硬编码的 BeanDefinitionRegistryPostProcessor 类型, 激活 postProcessBeanDefinitionRegistry 方法 // 2.获取所有配置的 BeanDefinitionRegistryPostProcessor 类型, 激活 postProcessBeanDefinitionRegistry 方法 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 记录通过硬编码方式注册的 BeanFactoryPostProcessor 类型处理器 List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 记录通过硬编码方式注册的 BeanDefinitionRegistryPostProcessor 类型处理器 List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 遍历所有硬编码注册的 BeanFactoryPostProcessor 处理器 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { // 如果是 BeanDefinitionRegistryPostProcessor 类型的处理器 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { // 将 BeanFactoryPostProcessor 强制类型转换为 BeanDefinitionRegistryPostProcessor BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 激活(调用) BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); // 将其保存到 registryProcessors 中 registryProcessors.add(registryProcessor); } else { // 将非 BeanDefinitionRegistryPostProcessor 类型的硬编码处理器注入对象直接保存到 regularPostProcessors 中 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. // 用于记录通过配置方式注册的 BeanDefinitionRegistryPostProcessor 类型的处理器 List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. // 获取所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 遍历所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName for (String ppName : postProcessorNames) { // 筛选出 PriorityOrdered 接口的实现类, 用于优先执行 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 从容器中获取 BeanName 对应的 BeanDefinitionRegistryPostProcessor 类型的 Bean 实例, 并将其添加到 currentRegistryProcessors 中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 记录 BeanName 对应的 BeanDefinitionRegistryPostProcessor 已经处理 processedBeans.add(ppName); } } // 对实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 类型的 Bean 进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 将其添加到 registryProcessors 中 registryProcessors.addAll(currentRegistryProcessors); // 激活 postProcessBeanDefinitionRegistry 方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); // 执行完后将集合清空 currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. // 获取所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 遍历所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName for (String ppName : postProcessorNames) { // 筛选出未经过处理的 && 实现 Ordered 接口的实现类, 用于第二执行 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { // 从容器中获取 BeanName 对应的 BeanDefinitionRegistryPostProcessor 类型的 Bean 实例, 并将其添加到 currentRegistryProcessors 中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 记录 BeanName 对应的 BeanDefinitionRegistryPostProcessor 已经处理 processedBeans.add(ppName); } } // 对实现 Ordered 接口的 BeanDefinitionRegistryPostProcessor 类型的 Bean 进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 将其添加到 registryProcessors 中 registryProcessors.addAll(currentRegistryProcessors); // 激活 postProcessBeanDefinitionRegistry 方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); // 执行完后将集合清空 currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. // 最后获取没有实现排序接口的 BeanDefinitionRegistryPostProcessor 类型的 Bean 进行激活, // 直到所有的 BeanDefinitionRegistryPostProcessors 类型注册的子类全部处理完毕才会退出 while 循环 boolean reiterate = true; while (reiterate) { reiterate = false; // 获取所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 遍历所有通过配置方式注册的 BeanDefinitionRegistryPostProcessor 的 BeanName for (String ppName : postProcessorNames) { // 将剩余(未实现 PriorityOrdered 和 Ordered 排序接口的子类)未处理过的 BeanName if (!processedBeans.contains(ppName)) { // 从容器中获取 BeanName 对应的 BeanDefinitionRegistryPostProcessor 类型的 Bean 实例, 并将其添加到 currentRegistryProcessors 中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 记录 BeanName 对应的 BeanDefinitionRegistryPostProcessor 已经处理 processedBeans.add(ppName); reiterate = true; } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 将其添加到 registryProcessors 中 registryProcessors.addAll(currentRegistryProcessors); // 激活 postProcessBeanDefinitionRegistry 方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); // 执行完后将集合清空 currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. // 至此, 所有的 BeanDefinitionRegistryPostProcessor 类型对象的 postProcessBeanDefinitionRegistry 方法已经全部激活完毕, // 开始激活其 postProcessBeanFactory 方法。 // registryProcessors 记录的是所有通过硬编码注册的 BeanDefinitionRegistryPostProcess invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // regularPostProcessors 记录的是所有通过硬编码注册的 BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } // 如果 beanFactory instanceOf BeanDefinitionRegistry 为 false // 则直接执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法即可。 // 因为 BeanDefinitionRegistryPostProcessor 接口中定义的 postProcessBeanDefinitionRegistry 方法需要的参数类型为 BeanDefinitionRegistry 类型的 BeanFactory else { // Invoke factory processors registered with the context instance. // 直接激活使用硬编码注册的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 至此, 所有通过硬编码注册的 BeanFactoryPostProcessor 已全部处理完成, 下面开始处理通过配置注册的后置处理器 // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // 获取所有的 BeanFactoryPostProcessor 类型的后置处理器的 BeanName, 用于后续处理 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<>(); // 遍历获取的所有 BeanFactoryPostProcessor 类型的后置处理器的 BeanName 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. // 排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 激活 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. // 激活实现了 Ordered 排序接口的 BeanFactoryPostProcessor 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. // 激活没有实现任何排序接口的 BeanFactoryPostProcessor 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(); }
源码具体实现很长,但是总结出来就我上面说的两点的具体实现。
至此,所有的BeanFactoryPostProcessor
已全部注册到容器中并且激活。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。
这篇关于Spring源码 - 容器刷新#invokeBeanFactoryPostProcessors()的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27本地多文件上传的简单教程
- 2024-11-27低代码开发:初学者的简单教程
- 2024-11-27如何轻松掌握拖动排序功能
- 2024-11-27JWT入门教程:从零开始理解与实现
- 2024-11-27安能物流 All in TiDB 背后的故事与成果
- 2024-11-27低代码开发入门教程:轻松上手指南
- 2024-11-27如何轻松入门低代码应用开发
- 2024-11-27ESLint开发入门教程:从零开始使用ESLint
- 2024-11-27Npm 发布和配置入门指南
- 2024-11-27低代码应用课程:新手入门指南