前言

上一篇文章中提到了在AbstractApplicationContext类的refresh方法中,可以通过invokeBeanFactoryPostProcessors方法,修改BeanDefinition对象。

今天这篇文章重点聊聊BeanFactoryPostProcessor,它的功能还是挺强大的,是Spring中一个非常重要的扩展点,在很多跟Spring集成的框架中,都对它进行了扩展。

1 BeanFactoryPostProcessor是干什么的?

我把Spring IOC的流程,简化为如下几个关键步骤:image

如果想在定义了BeanDefintion之后,再修改一下该怎么办呢?

答案是用:BeanFactoryPostProcessor

image该接口只包含一个方法:postProcessBeanFactory,在Spring的官方文档中有这样一段描述:

image允许自定义修改应用程序上下文的bean定义,调整上下文基础bean工厂的bean属性值。

说人话就是:允许我们动态修改bean的定义,并且修改bean的属性值。

我们接下来看看到底有哪些类实现了BeanFactoryPostProcessor接口呢?image

image这里有我们耳熟能详的关键字:Editor、Scope、PropertyPlaceholder等。其中:

  1. CustomEditorConfigurer是自定义类型转换器的。
  2. CustomScopeConfigurer是自定义Scope的。
  3. PropertyPlaceholderConfigurer是解析配置文件中配置参数的。

2 BeanFactoryPostProcessor的调用

在AbstractApplicationContext类中refresh方法中:image会调用invokeBeanFactoryPostProcessors和registerBeanPostProcessors方法。

让我们一起先看看invokeBeanFactoryPostProcessors方法:image会调用PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法:

image这个方法代码行数比较多,但是逻辑相对简单,由于上一篇文章已经介绍过了,我在这里就不过多分析了。

该方法的主要流程如下:image

上面的那段长逻辑,最终会调用invokeBeanFactoryPostProcessors方法:image在这个方法中会调用BeanFactoryPostProcessor类的postProcessBeanFactory方法,该方法就是Spring暴露给我们扩展的方法了。

终于找到你了!!!

3 BeanDefinitionRegistryPostProcessor的调用

前面已经介绍过BeanFactoryPostProcessor的用法了,接下来重点说说它的亲儿子:BeanDefinitionRegistryPostProcessor。

image该接口也只包含一个方法:postProcessBeanDefinitionRegistry,在Spring的官方文档中有这样一段描述:

image对标准BeanFactoryPostProcessor SPI的扩展,容许在进行常规BeanFactoryPostProcessor检测以前注册其余Bean定义。

特别是BeanDefinitionRegistryPostProcessor能够注册其余Bean定义,这些定义又定义了BeanFactoryPostProcessor实例。

说人话就是:允许我们动态的新增或者删除bean的定义。

在invokeBeanDefinitionRegistryPostProcessors方法中,可以非常直观的看到BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry是怎么被调用的:image此外,我们可以看到很多实现接口的类:image比如:apollo的ConfigPropertySourcesProcessor和SpringValueDefinitionProcessor类。

还有mybatis-spring中的MapperScannerConfigurer类。

在这里重点说一下,BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的调用顺序。

我们再回顾一下这张图:image先调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,允许用户动态新增和删除bean的定义。

再调用BeanFactoryPostProcessor类的postProcessBeanFactory方法,允许用户动态修改bean的定义和bean的属性。

这样一看,就变得顺理成章了。

4 BeanDefinitionRegistryPostProcessor的使用案例

前面提到在apollo的ConfigPropertySourcesProcessor类实现了BeanDefinitionRegistryPostProcessor接口,重新了它的postProcessBeanDefinitionRegistry方法。

我们一起来看看,它干了些什么。image在它里面向Spring容器注册了PropertySourcesPlaceholderConfigurer、ApolloAnnotationProcessor、SpringValueProcessor、ApolloJsonValueProcessor,这4个BeanDefinition。

这4个类不是普通的bean,它们要么实现了BeanPostProcessor接口,要么实现了BeanFactoryPostProcessor接口,是一些特殊的Processor,必须要通过这种方式注册到Spring容器中,这样这些Processor才能正确执行。

在SpringValueDefinitionProcessor类也实现了BeanDefinitionRegistryPostProcessor接口,重新了它的postProcessBeanDefinitionRegistry方法。image它的postProcessBeanDefinitionRegistry方法会调用processPropertyValues方法:image这个方法会把所有beanDefinition的属性值拿出来,放到beanName2SpringValueDefinitions这个全局的map当中。

5 BeanFactoryPostProcessor的使用案例

再一起看看BeanFactoryPostProcessor是怎么使用的。

我们一起看看CustomScopeConfigurer类:image这个类实现了BeanFactoryPostProcessor接口,重写了postProcessBeanFactory方法:

imageimage

这个方法逻辑很简单,就是变量scopes的map集合,根据不同的数据类型,调用不同的方法,将scope注册到Spring容器(beanFactory)当中。

这里用到了ConfigurableListableBeanFactory这个Spring容器的对象和它的方法。

这里没有去修改beanDefinition,只是使用了Spring容器对象而已。

好了,今天的内容分享到这里,我们下期再见。

最后修改:2026 年 06 月 05 日
如果觉得我的文章对你有用,请随意赞赏