likes
comments
collection
share

invokeBeanFactoryPostProcessors方法源码解析

作者站长头像
站长
· 阅读数 19

invokeBeanFactoryPostProcessors方法源码解析

基础脉络梳理

先来看一张图。梳理一下基本脉络,
大概粗略的讲 就是一堆类,spring会对他们进行遍历解析,继而new出来beanDefinition对象,
beanDefinition可以理解为spring对这个bean的抽象,还包括了这个bean的一些其他信息,比如它的scope,是否懒加载之类的,
spring实例化bean是和bean所对应的类所对应的beanDefinition有关,spring实例化bean和类没有直接关系,因为后置处理器postProcessor可以对beanDefinition的一些属性,比如beanClass属性。
接着把new出来的beanDefinition put进beanDefinitionMap,
然后调用所有BeanFactoryPostProcessor,遍历beanDefinitionMap,put进单例池。

小段子

BeanFactoryPostProcessor一被调用,spring框架里面其他对象便对他笑,
有的叫道,“你又被哪个码农给实例化了!”
他不回答,对spring框架说,“给我一个beandefinition对象”,说着便排出另外一个类D。 
他们又故意的高声嚷道,“你一定又要换了人家的东西了!”
他睁大眼睛说,“你怎么这样凭空污人清白......”
“什么清白?我上次亲眼见你换了Y的beanclass,吊着打。”
BeanFactoryPostProcessor便涨红了脸,额上的青筋条条绽出,争辩道,“替类不能算换......替类!......扩展代码的事,能算换么?”
接连便是难懂的逻辑,什么“忽略注入类型”,什么“清除缓存”之类,引得众人都哄笑起来;
spring内外充满了快活的空气

spring容器

怎么理解容器?容器其实是一个比较抽象的概念,就是一堆组件组合在一起完成bean的管理。
容器分为两种:BeanFactory和ApplicationContext.
BeanFactory: 这是一个简单的容器,如果把ApplicationContext比作现代文明社会,那么BeanFactory就是远古的石器时代,
它能够完成bean的实例化,bean的依赖注入,
然后BeanFactory中的bean都是懒加载的,所以早期使用BeanFactory能够节省很多资源,
但是现在科技发展的很好,很简单比如内存,就已经很大了,
所以现在绝大多数情况下,还是使用ApplicationContext容器。
ApplicationContext: 他的功能比较丰富,支持国际化、支持事件发布、支持 BeanPostProcessor的自动注册等。
他还有一个很经典的实现: AnnotationConfigApplicationContext.
这个容器有一个组件DefaultListableBeanFactory对象
这个对象中有一个重要的组件 beanDefinitionMap
主要来存储所有扫描出来的beandefinition,理解beanDefinitionMap先得阅读 invokeBeanFactoryPostProcessor方法

本文来分析spring初始化过程中refresh方法里面的invokeBeanFactoryPostProcessors方法,完成了扫描的工作,执行所有(spring认为可靠的)的可靠的BeanFactoryPostProcessors,直接实现了BeanFactoryPostProcessor 或者实现了BeanDefinitionRegistryPostProcessor

由于BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,所以下文出现的子类 指的就是BeanDefinitionRegistryPostProcessor,父类指的就是BeanFactoryPostProcessor。

invokeBeanFactoryPostProcessors流程解析

整个方法看起来很长,其实大概流程就是
1、先对所有实现了BeanDefinitionRegistryPostProcessor或者BeanFactoryPostProcessor的bean进行分类,装入list集合

2、首先执行实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor,一般情况,这里只能获取到spring内置的BeanDefinitionRegistryPostProcessor----ConfigurationClassPostProcessor(以下简称CCPP)
beanFactory.getBean 会去实例化CCPP 存在单例池里面,并且加入currentRegistryProcessors集合中
并且把name存入到processedBeans数组中,表示已经执行完了
然后遍历这个集合,执行里面子类的postProcessBeanDefinitionRegistry方法

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

3、然后执行实现了Ordered的BeanDefinitionRegistryPostProcessor,
并且如果processedBeans数组中已经存在了,就不会执行,防止重复执行。
然后依旧是beanFactory.getBean实例化,加入currentRegistryProcessors集合,并且存入processedBeans数组中

4、上面两步都类似,唯一不同的是 第一步是PriorityOrdered,第二步是Ordered。

5、接下来还有一个while()的“死循环”,循环的去查找执行子类,为什么还会有这一步,两个原因。
    1. 第二次找出来的BeanDefinitionRegistryPostProcessor 会动态添加新的 BeanDefinition
    2. 即不是PriorityOrdered也不是Ordered的子类。
这里的循环会持续直到不会出现新的BeanDefinitionRegistryPostProcessor为止

6、接下来调用刚才开头分类的list,执行父类BeanFactoryPostProcessor的方法
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 实现了子类的父类方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 执行通过api通过的直接实现了父类的方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

7、然后接下来就是找父类BeanFactoryPostProcessors,
也是分了三个list,一个是PriorityOrdered,一个是Ordered,一个是什么也没实现的父类,
如果上面处理BeanDefinitionRegistryPostProcessor的时候已经处理过,这里不再重复处理,
然后一次遍历list,执行父类的postProcessBeanFactory方法。

问题抛出

但是这里有一个问题
请看源码中的这三个list,PriorityOrdered的list是装的实例化对象,而另外两个是装的类名,
所以问题就是,为什么spring这里会先实例化priorityOrdered的父类?
// 实现了priorityOrdered的父类集合(实例化对象)
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 实现了order接口的父类集合(类名)
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)) {
      priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}

完整的源码注释

// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 保存所有调用过的PostProcessor的beanName,防止重复执行
Set<String> processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
   // 为了动态注册BeanDefinition
   BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
   // 存储所有实现了BeanFactoryPostProcessor的bean
   List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
   // 存储所有实现了BeanDefinitionRegistryPostProcessor的bean
   List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

   for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
      // 对已注册在DefaultListBeanFactory的BeanFactoryPostProcessor进行分类
      if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
         BeanDefinitionRegistryPostProcessor registryProcessor =
               (BeanDefinitionRegistryPostProcessor) postProcessor;
         // 已注册在DefaultListBeanFactory的BeanDefinitionRegistryPostProcessor优先级最高
         // 如果postProcessor是BeanDefinitionRegistryPostProcessor的实例
         // 执行postProcessor的postProcessBeanDefinitionRegistry
         registryProcessor.postProcessBeanDefinitionRegistry(registry);
         // 为什么执行完之后还要保存到List中呢?
         // 因为这里只是执行完了BeanDefinitionRegistryPostProcessor的回调
         // 父类BeanFactoryPostProcessor的方法还没有进行回调
         registryProcessors.add(registryProcessor);
      }
      else {
         // 如果不是BeanDefinitionRegistryPostProcessor的实例,则是BeanFactoryPostProcessor的实例
         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.
   // 定义了一个集合来存放当前需要执行的BeanDefinitionRegistryPostProcessor
   List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

   // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
   // 首先执行实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor
   // 这里只能获取到Spring内部注册的BeanDefinitionRegistryPostProcessor,因为到这里spring还没有去扫描Bean,获取不到我们通过@Component标志的自定义的BeanDefinitionRegistryPostProcessor
   // 一般默认情况下,这里只有一个beanName,
   // org.springframework.context.annotation.internalConfigurationAnnotationProcessor
   // 对应的BeanClass:ConfigurationClassPostProcessor
   // 根据类型查询到beanDefinitionMap,返回名字
   // 能不能找到? 一个--ConfigurationClassPostProcessor
   // postProcessorNames [ConfigurationClassPostProcessor]
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : postProcessorNames) {
      // 判断是否实现了PriorityOrdered接口
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         // 实例化 并且放到当前需要执行的集合当中
         // beanFactory.getBean 会去实例化ConfigurationClassPostProcessor 存在单例池里面
         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         // 表示已经处理完了
         processedBeans.add(ppName);
      }
   }
   // 排序 不需要关心排序
   sortPostProcessors(currentRegistryProcessors, beanFactory);
   // 合并 为什么要放到这个list当中?为了将来执行父类方法
   registryProcessors.addAll(currentRegistryProcessors);
   // 遍历执行,一般默认情况下,只有ConfigurationClassPostProcessor
   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
   // 清空这个集合,因为下次还要用
   currentRegistryProcessors.clear();

   // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
   // 第二步执行实现了Ordered的BeanDefinitionRegistryPostProcessor
   // 第二次找,可能因为第一次扫描完成后多了新的BeanDefinitionRegistryPostProcessor
   // postProcessorNames [ConfigurationClassPostProcessor,D,I]
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : postProcessorNames) {
      // !processedBeans.contains(ppName)防止重复执行
      // ConfigurationClassPostProcessor false
      // D true false
      // I true true
      if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
      }
   }
   sortPostProcessors(currentRegistryProcessors, beanFactory);
   registryProcessors.addAll(currentRegistryProcessors);
   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
   currentRegistryProcessors.clear();

   // 上面两步的套路是一模一样的,唯一不一样的地方是第一步执行的是实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor
   // 第二步是执行的是实现了Ordered的BeanDefinitionRegistryPostProcessor

   // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
   // 为什么还有第三次 两个原因
   // 1、第二次找出来的BeanDefinitionRegistryPostProcessor 会动态添加新的 BeanDefinition
   // 2、上面有条件判断,有的beanFactory.isTypeMatch(ppName, Ordered.class)是false
   // 直到不会出现新的BeanDefinitionRegistryPostProcessor为止
   boolean reiterate = true;
   // 默认是死循环
   while (reiterate) {
      // 终止循环
      reiterate = false;
      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);
            // 如果找到了,后面还需要继续循环 继续找
            // 找出来的 必然是子类BeanDefinitionRegistryPostProcessor 有可能会动态添加新的BeanDefinition
            reiterate = true;
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();
   }

   // 方法开头前几行分类的两个list就是在这里调用
   // BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
   // 刚刚执行了BeanDefinitionRegistryPostProcessor的方法
   // 现在要执行父类BeanFactoryPostProcessor的方法

   // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
   // 实现了子类的父类方法
   invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
   // 执行通过api通过的直接实现了父类的方法
   invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
   // 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!
// 找父类
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 实现了priorityOrdered的父类集合(实例化对象)
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 实现了order接口的父类集合(类名)
List<String> orderedPostProcessorNames = new ArrayList<>();
// 没有任何实现的父类集合(类名)
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
   // 上面处理BeanDefinitionRegistryPostProcessor的时候已经处理过,这里不再重复处理
   // 因为BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
   if (processedBeans.contains(ppName)) {
      // skip - already processed in first phase above
   }
   else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      // 为什么这里先实例化
      priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
   orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
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...
beanFactory.clearMetadataCache();

参考资料

子路老师对spring源码的分析