Skip to main content

Spring BeanFactoryPostProcessor执行顺序

1. 前言

在之前的文章《Spring BeanPostProcessor执行顺序问题》介绍过 BeanPostProcessor , 使用Spring框架的人可能会注意到这样一个类 BeanFactoryPostProcessorBeanPostProcessor 名称很接近。下面来看一下**BeanFactoryPostProcessor** 的作用。

BeanFactoryPostProcessor: Spring Bean Factory的前置处理器,允许自定义修改应用上下文的Bean的定义。同时可以调整上下文的底层bean工厂的bean属性值。常用的拓展接口如下:

常用的拓展接口类

类之间的继承关系如下:

image-20220201120007663

上面存在两个重要的接口:

  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor

接下来着重分析这两个接口的作用

2.接口的执行顺序

接下来从 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 实现类注入和执行顺序来看。

2.1 接口实现类在哪里注入?

用现在最常用的注解上下文来解析,通过 AnnotationConfigApplicationContext 源码发现,属性 AnnotatedBeanDefinitionReader 实例化有这样一段代码:

image-20220201123122834

跟进代码 AnnotationConfigUtils#registerAnnotationConfigProcessors 发现

image-20220201165201280

  1. ConfigurationClassPostProcessor 类的定义注册到了Spring容器中。

到这里就是 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 的接口的实现类注册到Spring容器

2.2 接口的执行顺序

通过 AnnotationConfigApplicationContext 源码发现在 refresh 方法中有执行 BeanFactoryPostProcessor 。最终调用的是调用了父类的 AbstractApplicationContext#refresh 方法,在方法中有这样一段代码:

image-20220201170035512

  1. 这里就是执行 BeanFactoryPostProcessor

我们看一下里面 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 接口的执行顺序,分析源码可以知道是通过 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 来执行,分为以下几个执行部分:

执行BeanDefinitionRegistryPostProcessor:

  • 从Spring容器中获取**BeanFactoryPostProcessor** 和 BeanDefinitionRegistryPostProcessor 的实现类

    image-20220201170822680

    Tips: 如果是BeanDefinitionRegistryPostProcessor的实现类同时执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法

  • 首先执行 BeanDefinitionRegistryPostProcessors#postProcessBeanDefinitionRegistry 实现了 PriorityOrdered 接口的

    image-20220201173137323

  • 然后执行 BeanDefinitionRegistryPostProcessors#postProcessBeanDefinitionRegistry 实现了 Ordered 接口的

    image-20220201173224200

  • 在执行剩下的 BeanDefinitionRegistryPostProcessors#postProcessBeanDefinitionRegistry

    image-20220201173343336

  • 接着执行 BeanDefinitionRegistryPostProcessor#postProcessBeanFactory 方法和 BeanFactoryPostProcessor#postProcessBeanFactory 方法

    image-20220201173753538

执行BeanFactoryPostProcessor执行:

  • 执行 BeanFactoryPostProcessor#postProcessBeanFactory 实现了 PriorityOrdered 接口的

    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  • 执行 BeanFactoryPostProcessor#postProcessBeanFactory 实现了 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);
  • 执行剩下的 BeanFactoryPostProcessor#postProcessBeanFactory

    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
    nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

通过上面的代码分析总结一下 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 执行顺序,如下图所示:

BeanFactoryPostProcessor执行流程图

  1. 首先应该执行 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
  2. 然后执行 BeanDefinitionRegistryPostProcessor#postProcessBeanFactory 方法
  3. 最后执行 BeanFactoryPostProcessor#postProcessBeanFactory 方法

Tips: BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的执行还和PriorityOrdered以及Ordered有关。

3. 总结

BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor 可通过Spring原生的实现来做一些用户自定义的拓展,例如 ConfigurationClassPostProcessor 可以受到启发我们可以自定义一些配置在类上面的注解,例如自定义和@Component类似的注解。