前言
上一篇文章中提到了在AbstractApplicationContext类的refresh方法中,可以通过invokeBeanFactoryPostProcessors方法,修改BeanDefinition对象。
今天这篇文章重点聊聊BeanFactoryPostProcessor,它的功能还是挺强大的,是Spring中一个非常重要的扩展点,在很多跟Spring集成的框架中,都对它进行了扩展。
1 BeanFactoryPostProcessor是干什么的?
我把Spring IOC的流程,简化为如下几个关键步骤:
如果想在定义了BeanDefintion之后,再修改一下该怎么办呢?
答案是用:BeanFactoryPostProcessor
该接口只包含一个方法:postProcessBeanFactory,在Spring的官方文档中有这样一段描述:
允许自定义修改应用程序上下文的bean定义,调整上下文基础bean工厂的bean属性值。
说人话就是:允许我们动态修改bean的定义,并且修改bean的属性值。
我们接下来看看到底有哪些类实现了BeanFactoryPostProcessor接口呢?
这里有我们耳熟能详的关键字:Editor、Scope、PropertyPlaceholder等。其中:
- CustomEditorConfigurer是自定义类型转换器的。
- CustomScopeConfigurer是自定义Scope的。
- PropertyPlaceholderConfigurer是解析配置文件中配置参数的。
2 BeanFactoryPostProcessor的调用
在AbstractApplicationContext类中refresh方法中:
会调用invokeBeanFactoryPostProcessors和registerBeanPostProcessors方法。
让我们一起先看看invokeBeanFactoryPostProcessors方法:
会调用PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法:
这个方法代码行数比较多,但是逻辑相对简单,由于上一篇文章已经介绍过了,我在这里就不过多分析了。
该方法的主要流程如下:
上面的那段长逻辑,最终会调用invokeBeanFactoryPostProcessors方法:
在这个方法中会调用BeanFactoryPostProcessor类的postProcessBeanFactory方法,该方法就是Spring暴露给我们扩展的方法了。
终于找到你了!!!
3 BeanDefinitionRegistryPostProcessor的调用
前面已经介绍过BeanFactoryPostProcessor的用法了,接下来重点说说它的亲儿子:BeanDefinitionRegistryPostProcessor。
该接口也只包含一个方法:postProcessBeanDefinitionRegistry,在Spring的官方文档中有这样一段描述:
对标准BeanFactoryPostProcessor SPI的扩展,容许在进行常规BeanFactoryPostProcessor检测以前注册其余Bean定义。
特别是BeanDefinitionRegistryPostProcessor能够注册其余Bean定义,这些定义又定义了BeanFactoryPostProcessor实例。
说人话就是:允许我们动态的新增或者删除bean的定义。
在invokeBeanDefinitionRegistryPostProcessors方法中,可以非常直观的看到BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry是怎么被调用的:
此外,我们可以看到很多实现接口的类:
比如:apollo的ConfigPropertySourcesProcessor和SpringValueDefinitionProcessor类。
还有mybatis-spring中的MapperScannerConfigurer类。
在这里重点说一下,BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的调用顺序。
我们再回顾一下这张图:
先调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,允许用户动态新增和删除bean的定义。
再调用BeanFactoryPostProcessor类的postProcessBeanFactory方法,允许用户动态修改bean的定义和bean的属性。
这样一看,就变得顺理成章了。
4 BeanDefinitionRegistryPostProcessor的使用案例
前面提到在apollo的ConfigPropertySourcesProcessor类实现了BeanDefinitionRegistryPostProcessor接口,重新了它的postProcessBeanDefinitionRegistry方法。
我们一起来看看,它干了些什么。
在它里面向Spring容器注册了PropertySourcesPlaceholderConfigurer、ApolloAnnotationProcessor、SpringValueProcessor、ApolloJsonValueProcessor,这4个BeanDefinition。
这4个类不是普通的bean,它们要么实现了BeanPostProcessor接口,要么实现了BeanFactoryPostProcessor接口,是一些特殊的Processor,必须要通过这种方式注册到Spring容器中,这样这些Processor才能正确执行。
在SpringValueDefinitionProcessor类也实现了BeanDefinitionRegistryPostProcessor接口,重新了它的postProcessBeanDefinitionRegistry方法。
它的postProcessBeanDefinitionRegistry方法会调用processPropertyValues方法:
这个方法会把所有beanDefinition的属性值拿出来,放到beanName2SpringValueDefinitions这个全局的map当中。
5 BeanFactoryPostProcessor的使用案例
再一起看看BeanFactoryPostProcessor是怎么使用的。
我们一起看看CustomScopeConfigurer类:
这个类实现了BeanFactoryPostProcessor接口,重写了postProcessBeanFactory方法:


这个方法逻辑很简单,就是变量scopes的map集合,根据不同的数据类型,调用不同的方法,将scope注册到Spring容器(beanFactory)当中。
这里用到了ConfigurableListableBeanFactory这个Spring容器的对象和它的方法。
这里没有去修改beanDefinition,只是使用了Spring容器对象而已。
好了,今天的内容分享到这里,我们下期再见。