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。
相关推荐
啊松同学17 分钟前
【Java】设计模式——工厂模式
java·后端·设计模式
枫叶_v1 小时前
【SpringBoot】20 同步调用、异步调用、异步回调
java·spring boot·后端
鸣弦artha1 小时前
蓝桥杯——杨辉三角
java·算法·蓝桥杯·eclipse
大波V51 小时前
设计模式-参考的雷丰阳老师直播课
java·开发语言·设计模式
计算机-秋大田1 小时前
基于微信小程序的平安驾校预约平台的设计与实现(源码+LW++远程调试+代码讲解等)
java·spring boot·微信小程序·小程序·vue·课程设计
《源码好优多》1 小时前
基于Java Springboot旅游信息推荐系统
java·spring boot·旅游
岁月无声code1 小时前
Spring Boot 牛刀小试 org.springframework.boot:spring-boot-maven-plugin:找不到类错误
java·spring boot·github
不爱学习的YY酱2 小时前
【计网不挂科】计算机网络第二章< 物理层 >习题库(含答案)
java·数据库·计算机网络
南城花随雪。2 小时前
Spring框架之装饰者模式 (Decorator Pattern)
java·开发语言·装饰器模式
编程、小哥哥2 小时前
设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
java·设计模式·装饰器模式