BeanDefinitionRegistryPostProcessor 原理说明

缘起

BeanDefinitionRegistryPostProcessor 是Spring提供的又一个扩展点. 为什么要说又? 因为Spring还提供了 BeanPostProcessor 和BeanFactoryPostProcessor两个扩展点. 详见【1】和【2】

分析

本文基于的demo是【3】和【4】.

我们来看【4】,【4】中我们注册了两个东西,一个是

1
2
3
4
5
6
7
8
9
10
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
...
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
...
}

另一个是

1
2
3
4
5
6
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
...
}

那么他们的接口方法是在什么时机被Spring框架调用的呢?

debug可以发现,调用栈如下

1
2
3
4
5
6
7
8
AnnotationConfigApplicationContext里面的refresh方法
-->
refresh方法中的
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
-->
然后一路跟到了
org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>)

第八行的源码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
...
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
...
registryProcessors.addAll(currentRegistryProcessors);
...
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
...
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
...
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
...

​ 源码1

其中第11(15)行的源码如下

org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor>, ConfigurableListableBeanFactory)

1
2
3
4
5
6
7
8
9
10
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}

​ 源码2

其实就是调用BeanFactoryPostProcessor实现类的postProcessBeanFactory接口方法.

而注意,第11行调用的是BeanDefinitionRegistryPostProcessor接口实现类们的postProcessBeanFactory接口方法,而第15行调用的是一般的BeanFactoryPostProcessor接口实现类的postProcessBeanFactory接口方法.

注意,这里的说法要是你知道BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口的话就不觉得奇怪了.至于源码1的第6行, 它的源码如下

org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor>, BeanDefinitionRegistry)

1
2
3
4
5
6
7
8
9
10
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}

即调用BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法.

所以就知道了顺序:

1
2
3
BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法先于
BeanDefinitionRegistryPostProcessor接口的postProcessBeanFactory方法先于
BeanFactoryPostProcessor接口的postProcessBeanFactory方法

BeanDefinitionRegistryPostProcessor一般用于添加新的组件

BeanFactoryPostProcessor一般用于修改既有的bean定义

BeanPostProcessor 一般用于bean初始化前后搞事情.

而且从源码1的4、8、13我们也知道了bean的来源.

参考

【1】https://yfsyfs.github.io/2019/06/10/BeanPostProcessor-%E5%8E%9F%E7%90%86%E6%B5%85%E6%9E%90/

【2】https://yfsyfs.github.io/2019/06/20/BeanFactoryPostProcessor%E7%9A%84%E5%8E%9F%E7%90%86/

【3】https://github.com/yfsyfs/backend/tree/master/spring-annotation-beandefinitionregistrypostprocessor

【4】https://github.com/yfsyfs/backend/tree/master/spring-annotation-beandefinitionregistrypostprocessor2