spring源码(四)调用beanFactory工厂处理器

图片

正文

前面一篇对beanFactory后置处理的大概流程进行了分析,也进行了大概的一个总结。现在进入到下一个流程。

1. invokeBeanFactoryPostProcessors方法

        // 所在类及方法:org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
        // Invoke factory processors registered as beans in the context.
        invokeBeanFactoryPostProcessors(beanFactory);

注释翻译过来就是:调用在上下文中注册为 bean 的工厂处理器。

    // 所在类及方法:org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
      PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
      // 省略部分代码、、、
   }

2. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors

上面的代码调用了PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法, 下面进入该方法,该方法代码比较多,也比较长,最好还是对这个方法进行断点调试,一步一步观察。

    // 所在类及方法:org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

      // Invoke BeanDefinitionRegistryPostProcessors first, if any. 
      // 首先调用BeanDefinitionRegistryPostProcessors类型的
      Set<String> processedBeans = new HashSet<>();//processedBeans用来保存已经被调用过的beanName。
        // beanFactory在创建时是使用的DefaultListableBeanFactory,而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,所以这里满足条件
      if (beanFactory instanceof BeanDefinitionRegistry) {
         BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
         // 定义BeanFactoryPostProcessor集合
         List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
         // 定义BeanDefinitionRegistryPostProcessor集合
         List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 遍历beanFactoryPostProcessors,对其进行分类然后放入对应的集合中
            // 在该处打断点,若是使用AnnotationConfigApplicationContext方式进入,则beanFactoryPostProcessors为null
            // 若是用springboot启动方式进入,beanFactoryPostProcessors里面是有值的,具体的这里就不细说了,感兴趣的可以打断点进去研究
         for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
               BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;
               registryProcessor.postProcessBeanDefinitionRegistry(registry);
               registryProcessors.add(registryProcessor);
            }
            else {
               regularPostProcessors.add(postProcessor);
            }
         }
            // 创建BeanDefinitionRegistryPostProcessor集合
         List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

         // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
         // 第一步,调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
         String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) { // 遍历筛选
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//筛选实现PriorityOrdered接口的
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);// 排序
         registryProcessors.addAll(currentRegistryProcessors); // 归类放入
         // 调用,在改处断点,currentRegistryProcessors中会有一个ConfigurationClassPostProcessor
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 
         currentRegistryProcessors.clear();// 清理

         // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
         // 然后 调用实现Ordered的BeanDefinitionRegistryPostProcessors
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            // 遍历筛选实现Ordered接口,且未被调用的。
            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);// 归类
        // 调用,断点调试发现这个地方的currentRegistryProcessors为null
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();// 清理

         // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
         // 最后,调用其他的BeanDefinitionRegistryPostProcessors,直到没有为止
         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);// 添加
            // 调用,断点调试,发现这个地方也是null
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();//清理
         }
         // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
         // 调用BeanFactoryPostProcessors的回调方法
         invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//BeanDefinitionRegistryPostProcessor的回调
         invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);// BeanFactoryPostProcessor的回调
      }
      else {
         // Invoke factory processors registered with the context instance.
         invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
      }
       // 下面就是调用BeanFactoryPostProcessor类型的bean了
      // 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.
      // 对beanFactory中已经注册的BeanFactoryPostProcessor进行分类,排序
      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)) {// 实现PriorityOrdered的
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
         }
         else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // 实现Ordered的
            orderedPostProcessorNames.add(ppName);
         }
         else {// 其他的
            nonOrderedPostProcessorNames.add(ppName);
         }
      }

      // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
       // 调用实现PriorityOrdered的BeanFactoryPostProcessors
      sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

      // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 调用实现Ordered的BeanFactoryPostProcessors
      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.
       // 最后,调用剩下的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();// 清理缓存
   }
   

这个方法的代码比较多,需要有耐心的去看。首先去看它的注释,把这个方法的大概流程,是干什么的了解清楚。其实这些代码的大概的一个流程还是比较简单的。 而且源码中的已有的注释也把大概流程解释得很清楚,自己也在上面写了一些注释。

这个方法主要就是执行BeanFactoryPostProcessors接口的实现类。需要注意的是:这些实现类, 要么是从参数beanFactoryPostProcessors 传入进来的,要么就是已经在beanFactory中注册好的,但是,在这个时候,beanFactory只是初始化了,是还没有对项目进行扫描的, 也就是说自动扫描还没开始,若要实现自定义BeanFactoryPostProcessors接口,那么spring应该是有方法去使自定义的接口生效的或者自己手动注册自定义接口的信息至beanFactory

还有一点就是,由于BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessors接口, 所以会先把实现BeanDefinitionRegistryPostProcessor接口的类筛选出来并调用 (具体在代码中的invokeBeanDefinitionRegistryPostProcessors方法,该方法就是循环去调用postProcessBeanDefinitionRegistry方法), 然后在调用剩下的实现类(具体在代码中的invokeBeanFactoryPostProcessors方法,该方法就是循环调用postProcessBeanFactory方法),而且这些实现类有可能还实现了PriorityOrdered接口及Ordered接口,又要以此进行筛选,排序。下面看一下他的流程图:

image.png

3. 分段

下面对上面的代码分段来看:

SpringBoot版本2.5.2spring-context版本5.2.8.RELEASE

3.1 入参处理(beanFactoryPostProcessors)

对传入的BeanFactoryPostProcessor参数进行分类,然后调用。其实就是挑选BeanDefinitionRegistryPostProcessor的实现, 然后调用postProcessBeanDefinitionRegistry方法

1
2
3
4
5
6
7
8
9
10
11
    for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
        }
        else {
            regularPostProcessors.add(postProcessor);
        }
    }

image.png

  • ConfigurationWarningsPostProcessor
  • CachingMetadataReaderFactoryPostProcessor

3.2 BeanDefinitionRegistryPostProcessor-PriorityOrdered

beanFactory中选出BeanDefinitionRegistryPostProcessor类型的bean,且实现了PriorityOrdered接口。

1
2
3
4
5
6
7
8
9
10
11
        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.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();

在这段代码的调试中,会发现只有一个类,就是ConfigurationClassPostProcessor类。

3.3 BeanDefinitionRegistryPostProcessor-Ordered

beanFactory中选出BeanDefinitionRegistryPostProcessor类型的bean,且实现了Ordered接口。

1
2
3
4
5
6
7
8
9
10
11
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
        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, beanFactory.getApplicationStartup());
    currentRegistryProcessors.clear();

断点调试,这个地方没有课执行的,也就是currentRegistryProcessorsnull

3.4 BeanDefinitionRegistryPostProcessor-other与回调

  1. 执行剩下的BeanDefinitionRegistryPostProcessor类型的bean,最后调用回调方法invokeBeanFactoryPostProcessors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    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, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear();
    }

    // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

3.5 BeanFactoryPostProcessor归类

获取beanFactory中的BeanFactoryPostProcessor,执行过的跳过,然后根据PriorityOrderedOrdered分类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
      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);
         }
      }

3.6 BeanFactoryPostProcessor调用与缓存清理

调用在第5步已经归类好的BeanFactoryPostProcessor,最后清理缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        // 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();

最后

从上面的代码中,知道了两个重要的接口,一个是BeanFactoryPostProcessor,另一个是BeanDefinitionRegistryPostProcessor接口。 其中BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口,但是两个接口的功能是不一样的,具体的就需要看他们各自的实现类是怎么样的了。

下面看看BeanFactoryPostProcessorpostProcessBeanFactory方法的注释:

1
2
3
4
5
6
7
8
9
    /**
	 * 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.
	 * 在标准初始化之后修改应用程序上下文的内部 bean 工厂.所有的bean定义都会被加载,但是并不会实例化bean。
	 * 这允许覆盖或者添加一些属性,甚至可以初始化bean。
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

下面在看看BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry方法的注释:

1
2
3
4
5
6
7
8
9
    /**
	 * 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.
	 * 在标准初始化后修改应用程序上下文的内部 bean 定义注册信息。所有的常规bean定义信息都将会被加载,但是并不会实例化bean。
	 * 这里允许在下一个后置处理阶段开始之前添加多个bean定义信息。
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

从上面的注释来看,BeanFactoryPostProcessor主要是针对对BeanFactory进行操作(修改,覆盖或其它), 而BeanDefinitionRegistryPostProcessor主要是对bean定义(BeanDefinition)进行操作(修改,覆盖或其它)。 他们各自的分工不同。但是BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,所以BeanDefinitionRegistryPostProcessor的实现类需要实现两者的对应的接口。

在调试的过程中,出现了一个ConfigurationClassPostProcessor的类,其实这个类才是整个方法执行过程中最重要的一个类。从这个名字就能大概看出来这个类是干啥的:处理配置类。 关于ConfigurationClassPostProcessor这里就不细说了。

坚持原创技术分享,您的支持将鼓励我继续创作!