spring invokeBeanFactoryPostProcessors 分析

首先从一段简单的代码开始

public class App {
    public static void main(String[] args) {
        ApplicationContext classPathXmlApplicationContext
                 = new ClassPathXmlApplicationContext("classpath:application.xml");

         UserService userService = (UserService) classPathXmlApplicationContext.getBean("userService");
        userService.getUserInfo();
    }
}

向容器注册了三个bean , 一个是 userService  , 一个是  自定义 BeanFactoryPostProcessor ,还有一个是  自定义   BeanDefinitionRegistryPostProcessor

 先看一下自定义 BeanFactoryPostProcessor的实习

 看一下该 BeanFactoryPostProcessor 接口 的作用

允许自定义修改应用程序上下文的bean定义,

调整上下文的底层bean工厂的bean属性值。

应用程序上下文可以自动检测 BeanFactoryPostProcessor bean

并在创建其他bean之前使用它们。

适用于针对系统管理员的自定义配置文件 覆盖应用程序上下文中配置的bean。请参见PropertyResourceConfigurer及其具体实现

用于解决此类配置需求的开箱即用解决方案。BeanFactoryPostProcessor可以与bean交互并修改bean定义,但绝不是bean实例。这样做可能会导致早产

实例化,违反容器并导致意外的副作用。

如果需要bean实例交互,请考虑实现BeanPostProcessor

  Allows for custom modification of an application context's bean definitions,
 * adapting the bean property values of the context's underlying bean factory.
 *
 * <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
 * their bean definitions and apply them before any other beans get created.
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context.
 *
 * <p>See PropertyResourceConfigurer and its concrete implementations
 * for out-of-the-box solutions that address such configuration needs.
 *
 * <p>A BeanFactoryPostProcessor may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.

也就是说我们可以可以对 BeanFactory 里的 BeanDefinition 进行修改,而不是bean实例,因为此时bean实例并没有初始化

参数就是 BeanFactory 

public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanFactoryProcessor 调用");
    }
}

 接着看一下自定义的   BeanDefinitionRegistryPostProcessor

看一下该接口的说明

Extension to the standard BeanFactoryPostProcessor SPI, allowing for the registration of further bean definitions before regular BeanFactoryPostProcessor detection kicks in. In particular, BeanDefinitionRegistryPostProcessor may register further bean definitions which in turn define BeanFactoryPostProcessor instances.

对标准beanfactorypostprocessor的扩展,允许在常规BeanFactoryPostProcessor检测开始之前注册更多的bean定义。特别地,BeanDefinitionRegistryPostProcessor可以注册更多的bean定义,这些定义反过来定义BeanFactoryPostProcessor实例。

 但是我们可以发现自定义 MyBeanFactoryRegistryPostProcessor 也有个postProcessBeanFactory 方法 , 打开 BeanDefinitionRegistryPostProcessor 源码,我们会发现 发现该类是继承 BeanFactoryPostProcessor ,所以也就说得通了

public class MyBeanFactoryRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("postProcessBeanDefinitionRegistry 调用");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory 调用");
    }
}

 

结果

 接着看一下 invokeBeanFactoryPostProcessors ,见面知义,主要是回调BeanDefinitionRegistryPostProcessor  以及 BeanFactoryPostProcessor 的方法

所以在这里我们自定义的 BeanDefinitionRegistryPostProcessor  以及 BeanFactoryPostProcessor

就会在这里调用

 public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {



​       // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        ​Set<String> processedBeans = new HashSet<>(); //记录处理过的BeanDefinition

​
        ​if (beanFactory instanceof BeanDefinitionRegistry) {

​            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

    ​        // 用来存放BeanFactoryPostProcessor对象
            ​List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

​            // 用来存放BeanDefinitionRegistryPostProcessor对象
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

​            //遍历 所有的BeanFactoryPostProcessor

​         for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {

​               if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {

​                   BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
​                       // 如果是BeanDefinitionRegistryPostProcessor类型,直接执行postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    ​registryProcessors.add(registryProcessor);
​                } else{
            ​           // 如果不是BeanDefinitionRegistryPostProcessor类型
            ​          // 则将外部集合中的BeanFactoryPostProcessor存放到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.

            // 此处的currentRegistryProcessors存放当前需要执行的BeanDefinitionRegistryPostProcessor
​           List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
​           // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 获取所有实现了BeanDefinitionRegistryPostProcessor接口的类名
​           String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,
                    true, false);

​
            ​for (String ppName : postProcessorNames) {

               // 判断当前类是否实现了PriorityOrdered接口
                ​if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            ​   // 将BeanDefinitionRegistryPostProcessor存入currentRegistryProcessors                 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            ​   // 提前存放到processedBeans,避免重复执行,但是此处还未执行
            ​        processedBeans.add(ppName);
            ​   }
            ​}

​        // 对currentRegistryProcessors接口中的BeanDefinitionRegistryPostProcessor进行排序,方便后续执行
        ​sortPostProcessors(currentRegistryProcessors, beanFactory);
         // 添加到registryProcessors集合,用于后续执行父接口的postProcessBeanFactory方法
        ​registryProcessors.addAll(currentRegistryProcessors);
        // 遍历集合,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法
        ​invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 执行完毕后,将currentRegistryProcessors清空
        ​currentRegistryProcessors.clear();



​           // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.

            // 这里为什么要再次获取BeanDefinitionRegistryPostProcessor

    ​      // 是因为有可能在上面方法执行过程中添加了BeanDefinitionRegistryPostProcessor,所以这里再次获取

    ​      // 而下面处理BeanFactoryPostProcessor的时候又不需要重复获取了是为什么呢?

    ​      // 因为添加BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor只能在BeanDefinitionRegistryPostProcessor

    ​      // 中添加,在BeanFactoryPostProcessor是无法添加的,具体看方法参数就懂了

            ​postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

            ​for (String ppName : postProcessorNames) {
                // 判断当前bean没有被执行过,并且实现了Ordered接口
                ​if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // getBean() 如果BeanFactory中没有该Bean则会去创建该Bean
                    ​currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    ​processedBeans.add(ppName);
                }
            }
            // 以下操作和上面是一样的,排序-->执行-->清空currentRegistryProcessors
            ​sortPostProcessors(currentRegistryProcessors, beanFactory);

            ​registryProcessors.addAll(currentRegistryProcessors);

            ​invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

            ​currentRegistryProcessors.clear();

​           // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.

            ​boolean reiterate = true;
            //最后处理没有实现Ordered与PriorityOrdered接口的BeanDefinitionRegistryPostProcessor

​            //一直循环执行,直到所有的  BeanDefinitionRegistryPostProcesso 都处理了
            while (reiterate) {

            ​reiterate = false;
            // 获取所有实现了BeanDefinitionRegistryPostProcessor接口的组件名
            ​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();

            ​}



​           // Now, invoke the postProcessBeanFactory callback of all processors handled so far.

           //调用到目前为止处理的所有处理器的 postProcessBeanFactory 回调。更准确的说应该是调用目前为止所有的BeanDefinitionRegistryPostProcessor的 postProcessBeanFactory方法
            ​invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

            ​invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

​           } else{

            // BeanFactory如果不归属于BeanDefinitionRegistry类型,则直接执行beanFactoryPostProcessor
​           // Invoke factory processors registered with the context instance.
​                   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!
        // 获取所有实现了BeanDefinitionPostProcessor接口的组件名

        ​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)) {
                    // 获取所有实现了PriorityOrdered 的 BeanDefinitionPostProcessor
                    ​priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            ​}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    // 获取所有实现了Ordered 的 BeanDefinitionPostProcessor
                ​orderedPostProcessorNames.add(ppName);
    ​         } else{
                    // 获取所有实现了其他没有调用过的 BeanDefinitionPostProcessor
                ​nonOrderedPostProcessorNames.add(ppName);
            ​}
​       }

        //这里直接使用的翻译,过程和上面差不多的

​       // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
       // 首先,调用实现PriorityOrdered的BeanFactoryPostProcessors
        ​sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

        ​invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

​       // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
       // 接下来,调用实现Ordered的BeanFactoryPostProcessors。

        ​List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();

        ​for (String postProcessorName : orderedPostProcessorNames) {

            ​orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));

        ​}

        ​sortPostProcessors(orderedPostProcessors, beanFactory);

        ​invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);



​       // Finally, invoke all other BeanFactoryPostProcessors.
        //最后,调用所有其他BeanFactoryPostProcessors

        ​List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();

        ​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...
       // 清除缓存的合并bean定义,因为后处理器可能修改了原始元数据,例如替换值中的占位符。。。

       ​beanFactory.clearMetadataCache();

​    }

 但是如果你通过源码调试的话会发现有两段代码总是不执行第二段很好理解,因为第一段代码不执行 所以 regularPostProcessors 总是为空 ,但是第一段代码为什么不执行呢

第一段

   for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {

​               if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {

​                   BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
​                       // 如果是BeanDefinitionRegistryPostProcessor类型,直接执行postProcessBeanDefinitionRegistry方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    ​registryProcessors.add(registryProcessor);
​                } else{
            ​           // 如果不是BeanDefinitionRegistryPostProcessor类型
            ​          // 则将外部集合中的BeanFactoryPostProcessor存放到regularPostProcessors用于后续一起执行
​                    regularPostProcessors.add(postProcessor);
                 }
           }

第二段 

这里其实就是调用我们提前往容器注册的 BeanFactoryPostProcessor,注意 这里并不是调用

xml里定义的 

​invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

 往上追溯我们发现原因是 beanFactoryPostProcessors 总是为空 而  beanFactoryPostProcessors 是调用invokeBeanFactoryPostProcessors 时作为参数传进来的 

也就是说在  getBeanFactoryPostProcessors() 时,由于容器中此时并没有 BeanFactoryPostProcessor 自然就获取不到了,那么该如何在这之前往 容器添加 BeanFactoryPostProcessor ,我们由 getBeanFactoryPostProcessors() 得出  addBeanFactoryPostProcessor(), 所以只需要查看 getBeanFactoryPostProcessors() 所在的类就可以了 ,发现两个都在 AbstracApplicaionContext 里 

看过源码继承树可知,该抽象类是我们的容器的上层接口 

 在看一下容器的创建过程

 

 注意这里的注释 ,翻译过来就是 允许在上下文子类中对bean工厂进行后处理  而且该方法是在 

invokeBeanFactoryPostProcessors  之前调用的, 所以我们只需要自定义自己的ApplicationContext 然后实现  postProcessBeanFactory 该方法就可以提提前往容器注册我们的

BeanDefinitionRegistryPostProcessor  以及 BeanFactoryPostProcessor 

public class MyApplicationContext extends ClassPathXmlApplicationContext {
    public  MyApplicationContext(String cofiguration){
            super(cofiguration);
    }
    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.postProcessBeanFactory(beanFactory);
        this.addBeanFactoryPostProcessor(new MyBeanFactoryRegistryPostProcessor(){
            @Override
            public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
                System.out.println("自定义容器添加调用 postProcessBeanDefinitionRegistry");
            }

            @Override
            public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
                System.out.println("自定义容器调用 postProcessBeanFactory ");
            }
        });
    }
}
public class App {
    public static void main(String[] args) {
        ApplicationContext classPathXmlApplicationContext
                 = new ClassPathXmlApplicationContext("classpath:application.xml");
        MyApplicationContext myApplicationContext = new MyApplicationContext("classpath:application.xml");
         UserService userService = (UserService) myApplicationContext.getBean("userService");
        userService.getUserInfo();
    }
}

 看一下最终结果 

 符合我们的预期

 调用流程为

1 提前存放的 BeanDefinitionRegistryPostProcessor 的  postProcessBeanDefinitionRegistry

2 实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor 的  postProcessBeanDefinitionRegistry 方法 

3 实现了 Ordered 的 BeanDefinitionRegistryPostProcessor 的  postProcessBeanDefinitionRegistry 方法 

4 其余的 BeanDefinitionRegistryPostProcessor 的  postProcessBeanDefinitionRegistry 方法 

5 所有的 BeanDefinitionRegistryPostProcessor 的  postProcessBeanFactory(提前注册的和 xml 定义的

方法 (和 1 的不一样,这里是执行的 xml 里定义的

6 所有提前注册的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法

7 执行所有实现了  PriorityOrdered 的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法

8 执行了所有实现了 Ordered 的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法

9 执行了其他 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法 (和 6 的不一样,这里是执行 xml 里定义的

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值