前言
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 方法还没有被执行。最后会循环执行。
- 如果不是 BeanDefinitionRegistry 类型,则直接执行传入的 beanFactoryPostProcessors 即可。
下面是对应的代码截图
以上只是这个方法的前半部分,执行了 BeanDefinitionRegistryPostProcessor 里面的 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
因为还有直接实现 BeanFactoryPostProcessor 的处理器,下面则开始处理 BeanFactoryPostProcessor 的处理器。过程和上面类似。
总结
通过以上的阅读,对 invokeBeanFactoryPostProcessors(beanFactory);
这一步方法进行总结。
BeanFactoryPostProcessor 作用
BeanFactoryPostProcessor 主要作用是在注册 BeanDefinition 之后,在 Bean 初始化之前,修改 BeanDefinition 的信息。
BeanFactoryPostProcessor 有个实现叫 BeanDefinitionRegistryPostProcessor,它可以额外的注册新的 BeanDefinition 到容器中。
流程概述
- 这一步主要是处理 BeanFactoryPostProcessor,分为两步。
- 执行 BeanDefinitionRegistryPostProcessor 接口里面的两个方法:postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
- 执行 BeanFactoryPostProcessor 接口里面的 postProcessBeanFactory 方法。