Spring BeanFactoryPostProcessor执行顺序
1. 前言
在之前的文章《Spring BeanPostProcessor执行顺序问题》介绍过 BeanPostProcessor
, 使用Spring框架的人可能会注意到这样一个类 BeanFactoryPostProcessor
和 BeanPostProcessor
名称很接近。下面来看一下**BeanFactoryPostProcessor
** 的作用。
BeanFactoryPostProcessor: Spring Bean Factory的前置处理器,允许自定义修改应用上下文的Bean的定义。同时可以调整上下文的底层bean工厂的bean属性值。常用的拓展接口如下:
类之间的继承关系如下:
上面存在两个重要的接口:
- BeanFactoryPostProcessor
- BeanDefinitionRegistryPostProcessor
接下来着重分析这两个接口的作用
2.接口的执行顺序
接下来从 BeanFactoryPostProcessor
和 BeanDefinitionRegistryPostProcessor
实现类注入和执行顺序来看。
2.1 接口实现类在哪里注入?
用现在最常用的注解上下文来解析,通过 AnnotationConfigApplicationContext 源码发现,属性 AnnotatedBeanDefinitionReader 实例化有这样一段代码:
跟进代码 AnnotationConfigUtils#registerAnnotationConfigProcessors 发现
- 将 ConfigurationClassPostProcessor 类的定义注册到了Spring容器中。
到这里就是 BeanFactoryPostProcessor
和 BeanDefinitionRegistryPostProcessor
的接口的实现类注册到Spring容器
2.2 接口的执行顺序
通过 AnnotationConfigApplicationContext 源码发现在 refresh 方法中有执行 BeanFactoryPostProcessor 。最终调用的是调用了父类的 AbstractApplicationContext#refresh
方法,在方法中有这样一段代码:
- 这里就是执行 BeanFactoryPostProcessor
我们看一下里面 BeanFactoryPostProcessor
和 BeanDefinitionRegistryPostProcessor
接口的执行顺序,分析源码可以知道是通过 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
来执行,分为以下几个执行部分:
执行BeanDefinitionRegistryPostProcessor:
-
从Spring容器中获取**
BeanFactoryPostProcessor
** 和BeanDefinitionRegistryPostProcessor
的实现类Tips: 如果是BeanDefinitionRegistryPostProcessor的实现类同时执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法
-
首先执行 BeanDefinitionRegistryPostProcessors#postProcessBeanDefinitionRegistry 实现了 PriorityOrdered 接口的
-
然后执行 BeanDefinitionRegistryPostProcessors#postProcessBeanDefinitionRegistry 实现了 Ordered 接口的
-
在执行剩下的 BeanDefinitionRegistryPostProcessors#postProcessBeanDefinitionRegistry
-
接着执行 BeanDefinitionRegistryPostProcessor#postProcessBeanFactory 方法和 BeanFactoryPostProcessor#postProcessBeanFactory 方法
执行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);
通过上面的代码分析总结一下 BeanFactoryPostProcessor
和 BeanDefinitionRegistryPostProcessor
执行顺序,如下图所示:
- 首先应该执行 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
- 然后执行 BeanDefinitionRegistryPostProcessor#postProcessBeanFactory 方法
- 最后执行 BeanFactoryPostProcessor#postProcessBeanFactory 方法
Tips: BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的执行还和PriorityOrdered以及Ordered有关。
3. 总结
BeanFactoryPostProcessor
和 BeanDefinitionRegistryPostProcessor
可通过Spring原生的实现来做一些用户自定义的拓展,例如 ConfigurationClassPostProcessor 可以受到启发我们可以自定义一些配置在类上面的注解,例如自定义和@Component类似的注解。