Spring BeanFactory后置处理器详解之配置类解析过程

24 篇文章 17 订阅
22 篇文章 11 订阅

BeanFactoryPostProcessor

BeanFactoryPostProcessor是spring的一大核心,也是一个扩展点之一,spring的配置类扫描解析就是使用了BeanFactoryPostProcessor来实现的;spring中的两大扩展点之一就是BeanFactory后置处理器和Bean的后置处理器,spring在设计上使用beanFactory的后置处理器来处理配置类解析,将配置类中配置的路径扫描成BeanDefinition放入beanDefinitionMap中,而Bean的后置处理器是Spring生命周期中非常重要的一环,比如处理生命周期回调,依赖注入@AutoWired、@Resource等都是使用了Spring bean后置处理器,所以spring也充分利用了它架构本身的扩展点来做很多事情;spring的BeanFactory后置处理器功能非常强大,spring在架构中将它放置于一个比较集中的处理位置,而且支持动态的植入你想要的处理器,你想要它执行的时机等都是非常容易的,spring在设计beanFactory的后置处理器中有两大要点:
1.基础的BeanFactory后置处理器可进行BeanDefinition的注册,移除等操作;
2.子类的BeanFactory后置处理器只能bean工厂进行操作,能够直接添加单例池,销毁单例池,但是不能对BeanDefinition进行添加操作。
spring基于上面的两个要点将beanFactory的后置处理器分为基类和子类,基类为:

@FunctionalInterface
public interface BeanFactoryPostProcessor {

   /**
    * Modify the application context's internal bean factory after its standard
    * initialization. All bean definitions will have been loaded, but no beans
    * will have been instantiated yet. This allows for overriding or adding
    * properties even to eager-initializing beans.
    * @param beanFactory the bean factory used by the application context
    * @throws org.springframework.beans.BeansException in case of errors
    */
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

这个是父类的BeanFactory后置处理器,在里面提供了一个方法postProcessBeanFactory,这个方法只要一个参数ConfigurableListableBeanFactory,这个参数类型只能对bean工厂进行bean的注册,bean的销毁,但是不能对BeanDefinition进行添加操作,所以这是父类提供的功能,也就是说后置处理器在执行这个方法的时候,那么spring是认为容器中的后置处理器是恒定的了,是不会产生了,请注意:它的执行时机是BeanFactory中执行了所有了它的子类的BeanDefinitionRegistryPostProcessor中的后置处理器方法postProcessBeanDefinitionRegistry后才执行的。

子类:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

   /**
    * Modify the application context's internal bean definition registry after its
    * standard initialization. All regular bean definitions will have been loaded,
    * but no beans will have been instantiated yet. This allows for adding further
    * bean definitions before the next post-processing phase kicks in.
    * @param registry the bean definition registry used by the application context
    * @throws org.springframework.beans.BeansException in case of errors
    */
   void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

子类BeanDefinitionRegistryPostProcessor 在父类的基础上提供了一种的新的职能postProcessBeanDefinitionRegistry表示可以对容器中的BeanDefinition进行添加,删除,并且还可以再次添加BeanFactory,Bean等一切操作,所以在执行bean的后置处理器逻辑过程中,它是最先执行的,它的执行时机就是在bean工厂的其他方法执行之前执行,保证容器中BeanDefinition是恒定的。

实现方式


public class Client {


   public static void main(String[] args) {

      AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
      ac.register(AppConfig.class);
      ac.addBeanFactoryPostProcessor(new BmlBeanFactoryPostProcessor());
      ac.refresh();




   }
   @Component
public class AutoBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("我是被扫描添加的");
   }


}
public class BmlBeanFactoryPostProcessor  implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("我是手动添加的");
   }


}

在容器执行的时候这两个都是会执行的,一个是加二零@Component注解的,一个是没有加这个注解的,是我手动添加进去的,实现起来都比较简单,使用是非常简单,但是要理解它的原理就不是那么容易的,需要点耐心。

BeanFactory后置处理器源码分析

spirng的源码的启动过程中,在注册了配置类过后,工厂准备完成过后就开始调用后置处理器了,我们看下调用beanFactory的后置处理器入口在哪里:
在这里插入图片描述
是在AbstractApplicationContext中的refresh中的invokeBeanFactoryPostProcessors调用的。

/**
 * 这里是调用工厂bean的后置处理器,bean工厂的后置处理器有两个
 * BeanFactoryPostProcessor和子类BeanDefinitionRegistryPostProcessor
 * 下面的方法主要是处理这两个后置处理器,其实spring的设计人员的核心思想是:
 * 1.bean工厂中的后置处理器分为了用户自定义的和spring内置的后置处理器,用户自定义的后置处理器分为手动添加的和扫描得到的
 * 如果手动添加的,那么先执行手动添加的后置处理器;
 * 2.如果是扫描得到的和spring内部的后置处理器是根据优先级来进行执行的,但是不管哪种情况的bean工厂后置处理器都是
 * 先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry,在执行父类中postProcessBeanFactory
 * 为什么这样做的,因为postProcessBeanDefinitionRegistry可以注册BeanDefinition,而postProcessBeanFactory不能注册
 * BeanDefinition,也就是说先把所有的能注册BeanDefinition的所有bean工厂后置处理器处理完成,才来对bean工厂中的
 * BeanDefinition进行统一处理
 * getBeanFactoryPostProcessors()这个方法获取的是用户手动添加的bean工厂后置处理器,如果你在启动的时候没有手动添加后置处理器
 * 那么这个方法获取的为空
 *
 */
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

spring的配置类解析是通过spring的baenfactory的后置处理器来完成的,我们想要分析出想要的结果,就要先知道原理,原理理解的前提就是要理解beanFactroy后置处理器的两大要点,在这两大要点的基础上去理解它的处理过程,在分析它的源码之前,我们来先看下它的执行流程:
在这里插入图片描述

invokeBeanFactoryPostProcessors分析

/**
 * 调用spring默认的后置处理器,最最重要的是ConfigurationClassPostProcessor,这个类扫描
 * 我们配置的类
 * @param beanFactory  bean工厂,子类是DefaultListableBeanFactory
 * @param beanFactoryPostProcessors 用户注册的BeanFactory后置处理器
 * 在这之前,我们的register和构造都没有注册过后置处理器,而我们的Import也还没被扫描
 * spring目前还没开始扫描,在这之前仅仅做了工厂初始化和默认的spring内置处理器,以及将我们的配置类注册
 * 到工厂的bdmap中 ,所以这里传入的beanFactoryPostProcessors如果在启动的时候没有添加后置处理器,那么这里传入的为空
 */
public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   /**
    * 下面的bean工厂后置处理器其实就是围绕BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor类进行的
    * 其中BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,子类中提供了一个方法postProcessBeanDefinitionRegistry
    * 是可以对BeanDefinition进行再次注册的,而BeanFactoryPostProcessor中提供的方法是不能进行注册BeanDefinition,只能对bean工厂就行
    * 处理的,所以实现了BeanDefinitionRegistryPostProcessor接口的bean具有两个功能,就是注册BeanDefinition和操作BeanFactory,
    * 这个设计人员的思路是将所有的bean的后置处理器中的注册BeanDefinition的方法全部执行了再次执行BeanFactoryPostProcessor,所以
    * 对下面的代码的执行顺序是执行所有实现了BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry
    * 在执行父类的postProcessBeanFactory
    * 这里执行的逻辑如下:
       * 1.循环执行用户手动添加的后置处理器列表,如果后置处理器实现了BeanDefinitionRegistryPostProcessor接口,那么执行
       * 接口中的postProcessBeanDefinitionRegistry方法;
       * 2.对容器中实现了BeanDefinitionRegistryPostProcessor接口并且实现了优先级的后PriorityOrdered置处理器执行接口中的postProcessBeanDefinitionRegistry方法;
       * 3.对容器中实现了BeanDefinitionRegistryPostProcessor接口并且实现了优先级的后Ordered置处理器执行接口中的postProcessBeanDefinitionRegistry方法;
       * 4.对容器中没有实现排序接口的后置处理器拿出来循环处理,每次循环获取一次容器中的实现了BeanDefinitionRegistryPostProcessor接口
       * 的后置处理器拿出来执行接口中的postProcessBeanDefinitionRegistry方法;然后设置循环为继续,直到取出所有的后置处理器执行。
       * 5.执行完所有后置处理器中postProcessBeanDefinitionRegistry,然后将所有执行过postProcessBeanDefinitionRegistry的后置处理器
       * 执行里面的每个后置处理器的postProcessBeanFactory;
       * 6.取出系统中所有实现了父类BeanFactoryPostProcessor接口的后置处理器拿出来;
       * 7.过滤掉上面已经执行过的postProcessBeanFactory的后置处理器,然后进行分组;
       * 8.实现了PriorityOrdered的分一组,实现了Ordered分一组,没有实现排序的分一组;
       * 9.分别执行每个分组中的工厂方法postProcessBeanFactory,然后结束。
    */

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   //这里定义个Set存放处理器的Bean名称(为啥用Set,因为Set自动具有自动去重功能),这里的这个processedBeans存放的
   //是已经执行过的后置处理器
   Set<String> processedBeans = new HashSet<>();
        //DefaultListableBeanFactory 肯定继承BeanDefinitionRegistry,所以这个条件肯定成立
   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      //regularPostProcessors是用来存放应用程序手动添加的自定义的BeanFactoryPostProcessor的子类(Bean工厂的后置处理器)
      //也就是说regularPostProcessors存放了实现了BeanFactoryPostProcessor接口的列表
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      //registryProcessors是用来存放应用程序手动添加的自定义的Bean注册工厂的后置处理器
      //也就是registryProcessors存放的是仅仅实现了BeanDefinitionRegistryPostProcessor类的后置处理器列表
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

      /**
       * 下面这个for循环是处理手动添加的后置处理器,如果实现了BeanDefinitionRegistryPostProcessor,那么先执行
       * postProcessBeanDefinitionRegistry,然后把这个后置处理器添加到registryProcessors,
       * 如果没有实现BeanDefinitionRegistryPostProcessor,那么肯定是实现了BeanFactoryPostProcessor
       * 添加到regularPostProcessors
       */
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            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,表示每次都存放符合条件的BeanDefinitionRegistryPostProcessor
       * 的beanFactory的后置处理器,然后放入过后,循环去执行里面的后置处理器的postProcessBeanDefinitionRegistry
       * 执行完成过后清空,然后下一个符合条件的后置处理器又添加进去,执行,就是一个临时变量。
       */
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      /**
       * 上面处理的是程序员手动添加的后置处理器,这里是要获取从beanDefinitionMap中注册的所有bean工厂的后置处理器
       * 但是代码执行到这里,我们的业务定义的bean还没有开始扫描的,这里最多获取的是spirng在启动开始添加到beanDefinitionMap
       * 中的后置处理器,所以这里的思路是:
       * 获取spring在启动添加到beanDefinitionMap中的bean工厂后置处理器,我们从前面的代码中可以知道spring只有在构建配置类读取
       * 对象的时候放了一个ConfigurationClassPostProcessor后置处理器,这个后置处理器是spring的核心,非常重要,是对我们的
       * 配置类进行解析,将配置类中符合条件的class生成BeanDefinition,然后放入到beanDefinitionMap
       *这里spring的官方的解释是first;实现逻辑是:
       * 1.将容器中所有实现了BeanDefinitionRegistryPostProcessor的beanName全部拿出来;
       * 2.将这些后置处理器实现了PriorityOrdered(优先级最高)的分为一组,然后getBean(如果没有,会创建)
       * 3.然后对这些实现了PriorityOrdered的后置处理器根据Order的数字进行排序,然后执行后置处理器中postProcessBeanDefinitionRegistry方法
       * 4.执行过的postProcessBeanDefinitionRegistry方法的后置处理器添加到执行过后的集合中processedBeans;
       * 5.currentRegistryProcessors表示当前执行的后置处理器(实现了BeanDefinitionRegistryPostProcessor接口的bean)
       * 每次循环将符合条件的后置处理器放入这个集合中,然后去执行,执行完成过后清除。
       *
       */
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {

         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            //将处理过的后置处理器名称放入processedBeans
            processedBeans.add(ppName);
         }
      }
      /**
       *  这个方法是排序的,就是上面找到的实现了BeanDefinitionRegistryPostProcessor的工厂后置处理器并且实现了PriorityOrdered
       *  优先级接口的后置处理器放入了currentRegistryProcessors,如果说这个集合中有4条数据,那么需要对这4条根据order的数字来排序
       *  判断哪个先执行,所以这里就是一个排序,不重要,只需要知道为什么要排序就行了。
       */
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      /**
       * 将上面实现了PriorityOrdered接口的后置处理器全部放入到registryProcessors,这个集合表示实现了BeanDefinitionRegistryPostProcessor
       * 的所有后置处理器集合,也就是说执行过BeanDefinitionRegistryPostProcessor这个接口里面的核心方法postProcessBeanDefinitionRegistry
       * 的所有后置处理器都放在这个集合里面
       */
      registryProcessors.addAll(currentRegistryProcessors);
      /**
       * 调用postProcessBeanDefinitionRegistry方法,除开程序员手动添加的后置处理器,这里有一个后置处理器就是spring在启动添加的
       * ConfigurationClassPostProcessor这个后置处理器,这个是解析我们配置类的,主要将我们配置类中配置的扫描路径下的所有
       * 符合条件的class扫描成BeanDefinition,然后放入beanDefinitionMap中
       * 所以我们的定义的扫描路径就是在下面这行代码执行的,也就是下面这行代码执行的后置处理器ConfigurationClassPostProcessor
       * 的postProcessBeanDefinitionRegistry执行的
       */
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      //执行完成过后,清空这个列表,下面的可以继续用,因为这里面的后置处理器都全部执行过了
      currentRegistryProcessors.clear();

      /**
       * 下面的和上面的代码一样的,唯一不一样的地方是上面的处理PriorityOrder的,下面的for是处理Ordered的
       * PriorityOrder的优先级最高,Ordered其次,spring官方的解释是next,也就是上面的是first,这里是next
       * 也就说这里都在处理BeanDefinitionRegistryPostProcessor,只是分了优先级,根据优先级来执行
       */

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //这里从容器里面拿出后置处理器,这里去单例工厂里面拿bean的时候第一次肯定不存在,不存在这里就会默认创建这个Bean
            //符合条件都添加到currentRegistryProcessors集合中,下面要就循环这个集合执行就可以了
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            //执行过的后置处理器都放入执行过的集合里面
            processedBeans.add(ppName);
         }
      }
      /**
       * 排序,和上面的一样,都是通过order的数字来排序,越小的数字越在前面,越先执行
       */
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      //将注册的后置处理器都放入到registryProcessors,和上面的一样
      registryProcessors.addAll(currentRegistryProcessors);
      //一样的调用invokeBeanDefinitionRegistryPostProcessors执行集合中的后置处理器
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      /**
       * spring的官方解释是finally,表示最后的一步,我们看下面的代码是用的循环来获取的;首先要明白上面的后置处理器中
       * 都只执行了PriorityOrder 和Ordered以及程序员手动添加的后置处理器;你想哈,前三步执行的后置处理器,都有可能添加BeanDefinition
       * 其中第二步是去解析我们的配置类的,肯定会将系统中程序员定义的所有的bean都扫描成了BeanDefinition,这里的代码逻辑就是说
       * 获取系统中的所有的后置处理器(实现了BeanDefinitionRegistryPostProcessor),不分优先级,下面的也是执行
       * BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法;下面的代码逻辑是:
       * 1.循环根据BeanDefinitionRegistryPostProcessor获取后置处理器名字列表;
       * 2.如果这个后置处理器已经执行过了,那么久不执行;
       * 3.如果没有执行过,添加到currentRegistryProcessors列表中;
       * 4.然后设置reiterate为true,表示我本次处理了后置处理器,容器中可能还有后置处理器,循环继续;
       * 5.然后对找到的符合条件的后置处理器开始执行;
       * 6.逻辑一样,处理完成过后添加到registryProcessors;
       * 7.然后清空已经还行过的后置处理器列表;
       * 下面我们来分析为什么这里要用循环,前面已经说了实现了BeanDefinitionRegistryPostProcessor的后置处理器中的
       * postProcessBeanDefinitionRegistry方法是可以注册BeanDefinition的,而可以注册BeanDefinition,也就意味着可以注册
       * BeanDefinitionRegistryPostProcessor类型的BeanDefinition,如果不用循环,不每次循环都去从新获取是否有BeanDefinitionRegistryPostProcessor
       * 类型的后置处理器,那么你在某一次的 postProcessBeanDefinitionRegistry方法中注册了新的BeanDefinitionRegistryPostProcessor类型
       * 的后置处理器,那系统不就漏掉了,漏处理了,所以这里用的是while循环,直到你每次获取到的后置处理器列表是空的,那么就表示系统中的所有
       * bean工厂的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);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      /**
       * 下面执行的是什么呢?首先来看下registryProcessors这个集合存放的是什么,这个集合存放的是系统中找到的所有
       * 实现了BeanDefinitionRegistryPostProcessor接口的后置处理器,而regularPostProcessors是实现了BeanFactoryPostProcessor
       * 的后置处理器列表,实现了BeanDefinitionRegistryPostProcessor必定实现了BeanFactoryPostProcessor
       * 而regularPostProcessors存放的是程序员手动添加的后置处理器;所以registryProcessors和regularPostProcessors
       * 包括了系统中的所有的bean工厂后置处理器,而上面的代码逻辑是已经将系统中的所有后置处理器中实现了BeanDefinitionRegistryPostProcessor
       * 中的postProcessBeanDefinitionRegistry都已经执行完成了,但是父类中的postProcessBeanFactory还没执行呢;
       * 所以下面的代码逻辑就是把系统中的所有后置处理器的postProcessBeanFactory方法全部执行
       *
       */
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      /**
       * spring的BeanFactoryPostProcessor的设计思想就是提供Bean的注册和工厂的的操作
       * 这个else意思就是说当前的bean工厂没有实现BeanDefinitionRegistry,那么就没有BeanDefinitionRegistry的
       * 一说了,就只能调用bean工厂的相关方法了,也就是只能调用postProcessBeanFactory,不能调用postProcessBeanDefinitionRegistry
       * 简单来说就是只实现了BeanFactoryPostProcessor,没有实现BeanDefinitionRegistryPostProcessor
       */
      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!
   /**
    * 下面的代码处理的是就是父类接口BeanFactoryPostProcessor接口中的postProcessBeanFactory方法了
    * 但是上面都已经执行过了,但是上面执行的是找到了实现了子类接口BeanDefinitionRegistryPostProcessor中的
    * 的postProcessBeanDefinitionRegistry和父类中postProcessBeanFactory方,但是只是找到了子类的类型的列表去执行的
    * 但是容器中肯定有只实现了BeanFactoryPostProcessor的后置处理器,只实现了父类的后置处理器也要拿出来执行它的后置处理方法
    * postProcessBeanFactory,但是拿出来的实现了父类的后置处理器也有可能把实现了子类的后置处理器也拿出来了,因为实现了子类也就实现了父类
    * 所以下面的逻辑需要把实现了子类的后置处理器给排除掉,也就是上面处理过的后置处理器都存放在了processedBeans中,所以下面的代码逻辑是:
    * 1.根据父类BeanFactoryPostProcessor得到容器中的所有后置处理器;
    * 2.过滤掉已经执行过的后置处理器;
    * 3.将剩下的后置处理器进行分类,实现了PriorityOrdered为一组,实现了Ordered一组,没有实现排序接口的为一组;
    * 4.根据每一组进行sort排序执行他们的工厂方法postProcessBeanFactory
    *
    */
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   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);
      }
   }

   // 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();
}

这个方法我的注释和原理说的很清楚,总结如下:
bean工厂后置处理器其实就是围绕BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor类进行的
其中BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,子类中提供了一个方法postProcessBeanDefinitionRegistry
是可以对BeanDefinition进行再次注册的,而BeanFactoryPostProcessor中提供的方法是不能进行注册BeanDefinition,只能对bean工厂就行
处理的,所以实现了BeanDefinitionRegistryPostProcessor接口的bean具有两个功能,就是注册BeanDefinition和操作BeanFactory,
这个设计人员的思路是将所有的bean的后置处理器中的注册BeanDefinition的方法全部执行了再次执行BeanFactoryPostProcessor,所以
对下面的代码的执行顺序是执行所有实现了BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry
在执行父类的postProcessBeanFactory
这里执行的逻辑如下:
1.循环执行用户手动添加的后置处理器列表,如果后置处理器实现了BeanDefinitionRegistryPostProcessor接口,那么执行 接口中的postProcessBeanDefinitionRegistry方法;
2.对容器中实现了BeanDefinitionRegistryPostProcessor接口并且实现了优先级的后PriorityOrdered置处理器执行接口中的postProcessBeanDefinitionRegistry方法;
3.对容器中实现了BeanDefinitionRegistryPostProcessor接口并且实现了优先级的后Ordered置处理器执行接口中的postProcessBeanDefinitionRegistry方法;
4.对容器中没有实现排序接口的后置处理器拿出来循环处理,每次循环获取一次容器中的实现了BeanDefinitionRegistryPostProcessor接口 的后置处理器拿出来执行接口中的postProcessBeanDefinitionRegistry方法;然后设置循环为继续,直到取出所有的后置处理器执行。
5.执行完所有后置处理器中postProcessBeanDefinitionRegistry,然后将所有执行过postProcessBeanDefinitionRegistry的后置处理器
执行里面的每个后置处理器的postProcessBeanFactory;
6.取出系统中所有实现了父类BeanFactoryPostProcessor接口的后置处理器拿出来;
7.过滤掉上面已经执行过的postProcessBeanFactory的后置处理器,然后进行分组;
8.实现了PriorityOrdered的分一组,实现了Ordered分一组,没有实现排序的分一组;
9.分别执行每个分组中的工厂方法postProcessBeanFactory,然后结束。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值