Spring实例化源码解析之registerBeanPostProcessors(六)

BeanPostProcessors是Spring框架中的一个扩展机制,它允许开发人员在Spring容器实例化、配置和初始化Bean的过程中干预和定制化。BeanPostProcessor接口定义了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization,分别在Bean初始化之前和之后被调用。

BeanPostProcessors的作用是在Bean的初始化过程中提供额外的处理逻辑。通过实现BeanPostProcessor接口并注册到Spring容器中,开发人员可以在Bean实例化后的早期和后期阶段对Bean进行修改、增强或执行其他自定义逻辑。这样可以实现很多功能,如属性注入、AOP代理、资源初始化等。

猜测

入口是在AbstractApplicationContext的refresh方法中,在方法中调用了registerBeanPostProcessors(beanFactory),从字面意思来说就是注册BeanPostProcessors,BeanPostProcessor具体做什么用的上面也有介绍,本章就分析一下这个注册做了哪些事情。

分析

老规矩,从入口的注释开始,这个方法就是实例化和注册所有的BeanPostProcessor,尊重期望的排序,如果有给出的话,这个方法必须在我们应用bean实力化之前被调用。

java 复制代码
/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

方法实际调用的是PostProcessorRegistrationDelegate类中的registerBeanPostProcessors方法,如果调用参数的详细入下截图所示:

PostProcessorRegistrationDelegate

这个类中的方法其实就是整个代码的核心,接下来我们继续用拆解的方式来进行分析,下面是其所有的代码块。

java 复制代码
public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   // 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

   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   // Register BeanPostProcessorChecker that logs an info message when
   // a bean is created during BeanPostProcessor instantiation, i.e. when
   // a bean is not eligible for getting processed by all BeanPostProcessors.
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, register the BeanPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
   sortPostProcessors(internalPostProcessors, beanFactory);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

步骤一:

直接通过类型去获取所有的BeanPostProcessor的BeanNames,存在postProcessorNames数组中。

java 复制代码
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

步骤二:

注册一个名为BeanPostProcessorChecker的BeanPostProcessor,并将其添加到beanFactory中。

具体分析如下:

  1. 获取已注册的BeanPostProcessor数量:

    java 复制代码
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount();
    ```
    这行代码获取已经注册到beanFactory的BeanPostProcessor的数量。
  2. 计算新的BeanPostProcessor的目标数量:

    java 复制代码
    beanProcessorTargetCount = beanProcessorTargetCount + 1 + postProcessorNames.length;
    ```
    在已有的BeanPostProcessor数量基础上,加上1(表示新注册的BeanPostProcessorChecker)以及postProcessorNames的长度(表示后续要注册的BeanPostProcessor的数量),计算出新的目标数量。
  3. 创建并注册BeanPostProcessorChecker:

    java 复制代码
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    ```
    创建一个名为BeanPostProcessorChecker的BeanPostProcessor实例,并将其添加到beanFactory中。
    
    BeanPostProcessorChecker是一个自定义的BeanPostProcessor,它在BeanPostProcessor实例化期间检查并记录信息。具体来说,当创建BeanPostProcessor期间创建了一个Bean(即一个Bean不符合所有BeanPostProcessor的处理条件)时,BeanPostProcessorChecker会记录一个信息日志。

步骤三:

对已注册的BeanPostProcessor进行分类,并按照优先级顺序注册到beanFactory中。

  1. 创建用于存储实现PriorityOrdered接口的BeanPostProcessor的列表:

    java 复制代码
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    ```
    创建一个名为priorityOrderedPostProcessors的列表,用于存储实现了PriorityOrdered接口的BeanPostProcessor。
  2. 创建用于存储内部BeanPostProcessor的列表:

    java 复制代码
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    ```
    创建一个名为internalPostProcessors的列表,用于存储内部的BeanPostProcessor。
  3. 创建用于存储实现Ordered接口的BeanPostProcessor名称的列表:

    java 复制代码
    List<String> orderedPostProcessorNames = new ArrayList<>();
    ```
    创建一个名为orderedPostProcessorNames的列表,用于存储实现了Ordered接口的BeanPostProcessor的名称。
  4. 创建用于存储未实现Ordered接口的BeanPostProcessor名称的列表:

    java 复制代码
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    ```
    创建一个名为nonOrderedPostProcessorNames的列表,用于存储未实现Ordered接口的BeanPostProcessor的名称。
  5. 遍历已注册的BeanPostProcessor名称列表,根据其类型进行分类:

    java 复制代码
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // BeanPostProcessor实现了PriorityOrdered接口
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 内部的BeanPostProcessor
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // BeanPostProcessor实现了Ordered接口
            orderedPostProcessorNames.add(ppName);
        }
        else {
            // 未实现Ordered接口的BeanPostProcessor
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
    ```
    遍历已注册的BeanPostProcessor名称列表postProcessorNames,根据名称对应的BeanPostProcessor的类型进行分类。如果BeanPostProcessor实现了PriorityOrdered接口,则将其添加到priorityOrderedPostProcessors列表中;如果是MergedBeanDefinitionPostProcessor的实例,则也添加到internalPostProcessors列表中;如果实现了Ordered接口,则将其名称添加到orderedPostProcessorNames列表中;否则,将其名称添加到nonOrderedPostProcessorNames列表中。
  6. 对实现PriorityOrdered接口的BeanPostProcessor进行排序:

    java 复制代码
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    ```
    调用sortPostProcessors方法对priorityOrderedPostProcessors列表中的BeanPostProcessor进行排序,按照优先级顺序进行排序。
  7. 注册实现PriorityOrdered接口的BeanPostProcessor到beanFactory中:

    java 复制代码
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    ```
    调用registerBeanPostProcessors方法,将priorityOrderedPostProcessors列表中的BeanPostProcessor注册到beanFactory中。

步骤四:

实现了Ordered接口的BeanPostProcessor到beanFactory中。

  1. 创建用于存储实现Ordered接口的BeanPostProcessor的列表:

    java 复制代码
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    ```
    创建一个名为orderedPostProcessors的列表,用于存储实现了Ordered接口的BeanPostProcessor。
  2. 遍历实现了Ordered接口的BeanPostProcessor的名称列表,并将它们实例化并添加到orderedPostProcessors列表中:

    java 复制代码
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            // 内部的BeanPostProcessor
            internalPostProcessors.add(pp);
        }
    }
    ```
    遍历实现了Ordered接口的BeanPostProcessor的名称列表orderedPostProcessorNames,通过beanFactory.getBean方法实例化每个BeanPostProcessor,并将其添加到orderedPostProcessors列表中。如果BeanPostProcessor是MergedBeanDefinitionPostProcessor的实例,则也添加到internalPostProcessors列表中。
  3. 对实现Ordered接口的BeanPostProcessor进行排序:

    java 复制代码
    sortPostProcessors(orderedPostProcessors, beanFactory);
    ```
    调用sortPostProcessors方法对orderedPostProcessors列表中的BeanPostProcessor进行排序,按照Ordered接口的顺序进行排序。
  4. 注册实现Ordered接口的BeanPostProcessor到beanFactory中:

    java 复制代码
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);
    ```
    调用registerBeanPostProcessors方法,将orderedPostProcessors列表中的BeanPostProcessor注册到beanFactory中。

步骤五:

注册剩余的未实现Ordered接口的BeanPostProcessor,并重新注册内部的BeanPostProcessor。

  1. 创建用于存储未实现Ordered接口的BeanPostProcessor的列表:

    java 复制代码
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    ```
    创建一个名为nonOrderedPostProcessors的列表,用于存储未实现Ordered接口的BeanPostProcessor。
  2. 遍历未实现Ordered接口的BeanPostProcessor的名称列表,并将它们实例化并添加到nonOrderedPostProcessors列表中:

    java 复制代码
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            // 内部的BeanPostProcessor
            internalPostProcessors.add(pp);
        }
    }
    ```
    遍历未实现Ordered接口的BeanPostProcessor的名称列表nonOrderedPostProcessorNames,通过beanFactory.getBean方法实例化每个BeanPostProcessor,并将其添加到nonOrderedPostProcessors列表中。如果BeanPostProcessor是MergedBeanDefinitionPostProcessor的实例,则也添加到internalPostProcessors列表中。
  3. 注册未实现Ordered接口的BeanPostProcessor到beanFactory中:

    java 复制代码
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
    ```
    调用registerBeanPostProcessors方法,将nonOrderedPostProcessors列表中的BeanPostProcessor注册到beanFactory中。
  4. 对内部的BeanPostProcessor进行排序:

    java 复制代码
    sortPostProcessors(internalPostProcessors, beanFactory);
    ```
    调用sortPostProcessors方法对internalPostProcessors列表中的BeanPostProcessor进行排序。
  5. 重新注册内部的BeanPostProcessor到beanFactory中:

    java 复制代码
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    ```
    调用registerBeanPostProcessors方法,将internalPostProcessors列表中的BeanPostProcessor重新注册到beanFactory中。
  6. 重新注册用于检测内部Bean作为ApplicationListeners的后处理器:

    java 复制代码
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    ```
    创建一个ApplicationListenerDetector的实例,并将其作为BeanPostProcessor添加到beanFactory中。这个后处理器用于检测内部Bean是否为ApplicationListeners,并将其移动到处理器链的末尾,以便在处理代理等情况时能够正确拾取内部Bean。
相关推荐
vipxieliang几秒前
Go 1.24 工具链改进实战:工具依赖管理与 go vet 新分析器
后端·go
掘金者阿豪几秒前
慢 SQL 优化别急着加索引:从订单分页查询聊聊 KES 执行计划
后端
萧瑟余晖1 分钟前
Spring Cloud Alibaba生态整合详解
spring·spring cloud·面试
涡能增压发动积2 分钟前
AI 对一位老开发的副作用总结
后端
她的男孩5 分钟前
条件分支两边审批一样,却发成两份待办:Forge Admin 审批设计器的公共节点合并
spring boot·低代码·工作流引擎
估值探索者11 分钟前
【Python量化技术指标实战 04】布林带通道突破,怎么知道是真突破还是假突破?
java·开发语言·python·接口·股票数据api接口
未秃头的程序猿12 分钟前
同一个商户号,V2 免密代扣和 V3 分账的证书怎么共存?
java·后端·微信
captain37626 分钟前
Spring Boot的配置文件
java·spring boot·后端
captain37627 分钟前
Spring Boot日志
java·数据库·spring boot
Rabitebla1 小时前
【Linux】 权限篇(三):深入理解 umask 位运算与粘滞位的设计思想
java·linux·服务器·c++·笔记·学习