Spring IOC容器初始化原理分析 (第三节)

327 阅读2分钟

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

1.前言

本文是Spring IOC容器初始化原理分析系列第三节,紧接上篇Spring IOC容器初始化原理分析 (第二节),其中本篇文章主要分析refresh() 中的 registerBeanPostProcessors(beanFactory)方法。

2.refresh() 源码

废话不多说,还是老规矩,先贴图,如果需要复制代码,可前往Spring IOC容器初始化原理分析 (第一节)

refresh.jpg

3.registerBeanPostProcessors(beanFactory)理解

这个方法必须要在bean实例化前调用,按照特定的顺序,实例化并注册所有BeanPostProcessor bean,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

在讲这个方法前,先来讲一下 BeanPostProcessor,Bean后置处理器。Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理,它是Spring中定义的接口,在Spring容器的创建过程中会回调BeanPostProcessor中定义的两个方法。在本方法中只是注册BeanPostProcessor,具体调用是在Bean初始化前后

图片.png

  • BeanPostProcessor 它是一个接口,其中包含了两个方法,postProcessBeforeInitialization 这个方法主要是在 bean初始化前调用 ,postProcessAfterInitialization 这个方法 主要是在bean初始化后调用

接下来 我们继续看 registerBeanPostProcessors(BeanFactory)方法

图片.png

里面就一行代码,接着点进去

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   //首先拿到所有的实现了BeanPostProcessor接口的类名
   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.
   
   //注册BeanPostProcessorChecker,当bean在BeanPostProcessor实例化期间创建时,
   //即当bean不符合所有BeanPostProcessors处理的条件时,该checker会记录信息消息。
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   //把刚刚注册的BeanPostProcessorChecker添加到beanFactory中去
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   
   // 定义不同的集合 用于记录实现了不同排序接口的 BeanPostProcessors
   
   //记录实现了PriorityOrdered接口的 BeanPostProcessors
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   // 记录实现了MergedBeanDefinitionPostProcessor接口的 BeanPostProcessors
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   // 记录实现了 Ordered接口的 BeanPostProcessors的beanName
   List<String> orderedPostProcessorNames = new ArrayList<>();
   // 记录实现了 没有实现排序接口的 BeanPostProcessors的beanName
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   
   // 遍历postProcessorNames,按照类型加入到对应的list集合中
   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.
   // 首先 对记录了 实现PriorityOrdered接口的BeanPostProcessors集合 进行排序
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   // 点进去这个方法他们把每一个BeanPostProcessors 注册到容器中去
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   
   // 其次,通过orderedPostProcessorNames集合记录的beanName 找到对应的 BeanPostProcessors
   // 同时判断是否有实现了MergedBeanDefinitionPostProcessor接口的,如果有就把它加入到
   //internalPostProcessors集合中去,然后把所有实现了Ordered接口的 BeanPostProcessors 先排序后注册到容器中去
   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.
   // 这里的操作和上面对于实现Ordered接口的 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.
   
   // 最后注册所有实现了 MergedBeanDefinitionPostProcessor 接口的 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).
   
   // 重新注册后置处理器 用于检测内部bean作为ApplicationListeners,将其移动到处理器链的末尾
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

4.重点总结

这个方法主要作用就是在bean实例化之前,实例化并注册所有 BeanPostProcessor。 其中有几个特殊的BeanPostProcessor,我们挑出来讲一讲

4.1 BeanPostProcessorChecker

这个后置处理器的主要作用是:记录创建bean时,所有的BeanPostProcessor都不能处理的bean,这个类的实例对象用于这个不能被处理的bean的信息,把这些信息以日志的形式打印出来。 源代码贴在下面 大家有兴趣的可以自己看看 org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker

图片.png

4.2 MergedBeanDefinitionPostProcessor

我们发现在public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext)方法中,会把所有实现了MergedBeanDefinitionPostProcessor接口的类 单独抽出来放在一个集合中

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

   //对指定的bean 合并属性信息,这里主要是子类(扫描注解里的信息,合并到bean中)
  void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

   //通知指定名称的bean定义已被重置,并且此后处理器应清除受影响bean的任何元数据。
  default void resetBeanDefinition(String beanName) {
  }

}

贴出一下它的子类 有兴趣大家可以继续关注

图片.png

4.3 ApplicationListenerDetector

  • ApplicationListenerDetector 主要作用就是处理 处理用户自定义的ApplicationListener的注册和销毁

  • 在Bean初始化完成之后:如果Bean是单例的则并且bean instanceof ApplicationListener。则把它注册到this.applicationListeners中。

  • 在ApplicationListener销毁之前,则会从ApplicationEventMulticaster(事件广播器)中提前删除了。

4.4 小结

后续源码将接着在本专栏 继续分析,如有兴趣,可订阅本专栏