BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的一个子接口
:::info
BeanDefinitionRegistryPostProcessor调用时机分析
:::
BeanDefinitionRegistryPostProcessor作为BeanFactoryPostProcessor的子接口,当用户自定义BeanDefinitionRegistryPostProcessor的时候,必将同时实现两个方法,postProcessBeanDefinitionRegistry和父方法postProcessBeanFactory
- 从IOC容器中获取到所有的BeanDefinitionRegistryPostProcessor组件
- 并依次触发它们的postProcessBeanDefinitionRegistry方法
- 然后再来触发它们的postProcessBeanFactory方法
- 再来从IOC容器中获取到所有的BeanFactoryPostProcessor组件,并依次触发它们的postProcessBeanFactory方法
今天我们重点来看BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法:
它的参数是BeanDefinitionRegistry,顾名思义就是与BeanDefinition注册相关的。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {// 注册bean到spring容器中void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;}
通过观察Spring自动注入类BeanDefinitionRegistry,我们发现它里边包含了registerBeanDefinition方法,这个不就是我们想要的吗?
为了能更好的使用该接口来达到注入Bean的目的,我们先来看看Spring是如何操作此接口的。

从invokeBeanFactoryPostProcessors方法入手,优先执行BeanDefinitionRegistry类型的beanFactory
上述源码依次执行实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor和实现了Ordered的BeanDefinitionRegistryPostProcessor
进入BeanDefinitionRegistryPostProcessor接口的生效方法invokeBeanDefinitionRegistryPostProcessors,进一步发现,BeanDefinitionRegistryPostProcessor类的postProcessBeanDefinitionRegistry方法会被调用
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry){Iterator var2 = postProcessors.iterator();while(var2.hasNext()) {BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();postProcessor.postProcessBeanDefinitionRegistry(registry);}}
退出invokeBeanDefinitionRegistryPostProcessors方法,最后执行父接口BeanFactoryPostProcessor
:::info
代码验证
:::
接下来编写测试代码进行验证。编写一个类MyBeanDefinitionRegistryPostProcessor,实现BeanDefinitionRegistryPostProcessor接口
package com.meimeixia.ext;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.support.AbstractBeanDefinition;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;import org.springframework.beans.factory.support.RootBeanDefinition;import org.springframework.stereotype.Component;import com.meimeixia.bean.Blue;// 记住,我们这个组件写完之后,一定别忘了给它加在容器中@Componentpublic class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// TODO Auto-generated method stubSystem.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:" + beanFactory.getBeanDefinitionCount());}/*** 这个BeanDefinitionRegistry就是Bean定义信息的保存中心,这个注册中心里面存储了所有的bean定义信息,* 以后,BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息来创建bean实例的。** bean定义信息包括有哪些呢?有这些,这个bean是单例的还是多例的、bean的类型是什么以及bean的id是什么。* 也就是说,这些信息都是存在BeanDefinitionRegistry里面的。*/@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {// TODO Auto-generated method stubSystem.out.println("postProcessBeanDefinitionRegistry...bean的数量:" + registry.getBeanDefinitionCount());// 除了查看bean的数量之外,我们还可以给容器里面注册一些bean,我们以前也简单地用过/** 第一个参数:我们将要给容器中注册的bean的名字* 第二个参数:BeanDefinition对象*/// RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); // 现在我准备给容器中添加一个Blue对象// 咱们也可以用另外一种办法,即使用BeanDefinitionBuilder这个构建器生成一个BeanDefinition对象,很显然,这两种方法的效果都是一样的AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();registry.registerBeanDefinition("hello", beanDefinition);}}
接下来,我们就来测试一下以上类里面的两个方法是什么时候执行的。运行IOCTest_Ext测试类,我们可以得出这样两个结论
- BeanDefinitionRegistryPostProcessor接口是优先于BeanFactoryPostProcessor接口执行的
- 在BeanDefinitionRegistryPostProcessor接口中,postProcessBeanDefinitionRegistry方法优先于postProcessBeanFactory方法调用 ```shell postProcessBeanDefinitionRegistry…bean的数量: 10 MyBeanDefinitionRegistryPostProcessor…bean的数量:11
MyBeanFactoryPostProcessor…postProcessBeanFactory…
当前BeanFactory中有9个Bean
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor,…,
…,org.springframework.context.event.internalEventListenerFactory,extConfig,myBeanFactoryPostProcessor,blue}
blue…constructor
``
可以看到,首先postProcessBeanDefinitionRegistry方法先执行,拿到IOC容器中Bean的数量(即10)之后向IOC容器中注册一个hello组件。<br />接着是postProcessBeanFactory`方法再执行,该方法只是打印了一下IOC容器中Bean的数量11(算上hello)
除此之外,我们自己写的MyBeanDefinitionRegistryPostProcessor类里面的方法都执行完了以后,才轮到外面那些BeanFactoryPostProcessor来执行
