• 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实力化之前被调用。

    /**
    	 * Instantiate and register all BeanPostProcessor beans,
    	 * respecting explicit order if given.
    	 * 

    Must be called before any instantiation of application beans. */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    PostProcessorRegistrationDelegate

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

    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));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    步骤一:

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

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

    步骤二:

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

    具体分析如下:

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

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

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

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

    步骤三:

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

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

      List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
      ```
      创建一个名为priorityOrderedPostProcessors的列表,用于存储实现了PriorityOrdered接口的BeanPostProcessor
      • 1
      • 2
      • 3
      • 4
    2. 创建用于存储内部BeanPostProcessor的列表:

      List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
      ```
      创建一个名为internalPostProcessors的列表,用于存储内部的BeanPostProcessor
      • 1
      • 2
      • 3
      • 4
    3. 创建用于存储实现Ordered接口的BeanPostProcessor名称的列表:

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

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

      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列表中。
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    6. 对实现PriorityOrdered接口的BeanPostProcessor进行排序:

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

      registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
      ```
      调用registerBeanPostProcessors方法,将priorityOrderedPostProcessors列表中的BeanPostProcessor注册到beanFactory中。
      
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    步骤四:

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

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

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

      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列表中。如果BeanPostProcessorMergedBeanDefinitionPostProcessor的实例,则也添加到internalPostProcessors列表中。
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    3. 对实现Ordered接口的BeanPostProcessor进行排序:

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

      registerBeanPostProcessors(beanFactory, orderedPostProcessors);
      ```
      调用registerBeanPostProcessors方法,将orderedPostProcessors列表中的BeanPostProcessor注册到beanFactory中。
      
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    步骤五:

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

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

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

      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列表中。如果BeanPostProcessorMergedBeanDefinitionPostProcessor的实例,则也添加到internalPostProcessors列表中。
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    3. 注册未实现Ordered接口的BeanPostProcessor到beanFactory中:

      registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
      ```
      调用registerBeanPostProcessors方法,将nonOrderedPostProcessors列表中的BeanPostProcessor注册到beanFactory中。
      
      
      • 1
      • 2
      • 3
      • 4
    4. 对内部的BeanPostProcessor进行排序:

      sortPostProcessors(internalPostProcessors, beanFactory);
      ```
      调用sortPostProcessors方法对internalPostProcessors列表中的BeanPostProcessor进行排序。
      
      
      • 1
      • 2
      • 3
      • 4
    5. 重新注册内部的BeanPostProcessor到beanFactory中:

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

      beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
      ```
      创建一个ApplicationListenerDetector的实例,并将其作为BeanPostProcessor添加到beanFactory中。这个后处理器用于检测内部Bean是否为ApplicationListeners,并将其移动到处理器链的末尾,以便在处理代理等情况时能够正确拾取内部Bean
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
  • 相关阅读:
    Mac上多版本JDK安装和管理
    一文搞懂ES6基本全部语法
    【亲测可用】图像目标识别入门-利用笔记本电脑摄像头识别人脸标记出来采用深度学习模型实现
    计算机毕业设计(附源码)python影院售票系统
    视觉任务相关的问题汇总
    Linux高性能服务器编程 学习笔记 第七章 Linux服务器程序规范
    基于SpringBoot+微信小程序的医院预约叫号小程序
    MySQL基础入门教程(InsCode AI 创作助手)
    安全狗陈荣有:打造“即开即用”的云原生安全能力
    Vue用户鉴权(权限指令与权限组件的设置思想)
  • 原文地址:https://blog.csdn.net/Tanganling/article/details/133531660