Spring BeanFactoryPostProcessor:机制解读与代码实践
BeanFactoryPostProcessor:机制解读与代码实践
- 一、BeanFactoryPostProcessor 基本知识总结
- 1.1 核心定义与作用
- 1.2 执行时机
- 1.3 与BeanPostProcessor的区别
- 二、BeanFactoryPostProcessor 使用姿势
- 2.1 修改现有 Bean 的定义
- 2.2 注册新 Bean 定义
- 2.3 全局配置处理
- 三、BeanFactoryPostProcessor 源码解析
- 3.1 接口源码
- 3.2 执行原理 - 源码分析
- 四、框架级应用案例与源码解析
- 4.1 ConfigurationClassPostProcessor 实现原理与源码解析
- 4.2 PropertySourcesPlaceholderConfigurer 实现原理与源码解析
- 五、高频面试题与解析
- 5.1 什么是 BeanFactoryPostProcessor?它的作用是什么?
- 5.2 BeanFactoryPostProcessor与BeanPostProcessor的区别?
- 5.3 如何自定义一个 BeanFactoryPostProcessor?请举例说明。
- 5.4 BeanFactoryPostProcessor的执行顺序如何控制?
- 5.5 为什么 PropertySourcesPlaceholderConfigurer 是 BeanFactoryPostProcessor 的典型实现?
一、BeanFactoryPostProcessor 基本知识总结
1.1 核心定义与作用
BeanFactoryPostProcessor是Spring框架中的一个关键扩展点(位于org.springframework.beans.factory.config包),其核心功能是在Bean实例化之前修改Bean的配置元数据(即BeanDefinition)。通过该接口,开发者可以在容器启动时动态调整Bean属性(如作用域、懒加载、属性值)、注册新的Bean定义,甚至替换现有Bean的实现类
public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
1.2 执行时机
- 在Spring容器加载完所有Bean定义后,Bean实例化之前(即BeanDefinition解析完成但未实例化时)触发
- 其子接口BeanDefinitionRegistryPostProcessor的执行时机更早,允许在Bean定义注册前进行扩展
1.3 与BeanPostProcessor的区别
对比维度 BeanFactoryPostProcessor BeanPostProcessor 操作对象 BeanDefinition(Bean配置元数据) Bean实例(已初始化对象) 执行时机 容器启动时,Bean实例化前 Bean实例化及初始化前后 典型应用 修改Bean属性、注册BeanDefinition 代理Bean、AOP增强、属性注入后处理 二、BeanFactoryPostProcessor 使用姿势
2.1 修改现有 Bean 的定义
场景:动态修改Bean的作用域(如scope)、懒加载策略(lazy-init)、属性值等。
代码示例:
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService"); // 修改作用域为单例 beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); // 修改属性值 MutablePropertyValues pv = beanDefinition.getPropertyValues(); pv.addPropertyValue("desc", "Modified by BeanFactoryPostProcessor"); } }
关键类:
- BeanDefinition:存储Bean的配置元数据,如属性、作用域等。
- MutablePropertyValues:提供对Bean属性值的动态修改能力 。
2.2 注册新 Bean 定义
场景:动态注册新的Bean到容器中(如基于条件动态生成Bean)。
代码示例:
@Component public class DynamicBeanRegistrar implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { GenericBeanDefinition newDefinition = new GenericBeanDefinition(); newDefinition.setBeanClass(NewService.class); registry.registerBeanDefinition("newService", newDefinition); } }
关键点:
- 使用BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor 的子接口)扩展注册能力
2.3 全局配置处理
场景:统一处理所有Bean的配置(如全局设置默认值)。
代码示例:
@Component public class GlobalConfigProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { Arrays.stream(beanFactory.getBeanDefinitionNames()) .filter(name -> beanFactory.getBeanDefinition(name).getBeanClassName().contains("Controller")) .forEach(name -> { BeanDefinition definition = beanFactory.getBeanDefinition(name); definition.setLazyInit(true); // 所有Controller类设为懒加载 }); } }
三、BeanFactoryPostProcessor 源码解析
3.1 接口源码
public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
子接口扩展:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
BeanDefinitionRegistryPostProcessor 与 BeanFactoryPostProcessor关系
- 继承关系:BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。这意味着BeanDefinitionRegistryPostProcessor不仅拥有父接口的功能,还增加了新的能力。
- 执行顺序:在 Spring 容器启动的过程中,会先执行BeanDefinitionRegistryPostProcessor,之后才会执行BeanFactoryPostProcessor。(稍后会有源码解析)
主要差异
对比维度 BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor 核心作用 能够对BeanDefinitionRegistry进行操作,比如动态注册、修改或者删除BeanDefinition 主要用于对ConfigurableListableBeanFactory进行修改,像调整 bean 的属性值。 关键方法 postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 执行时机 在所有标准BeanDefinition加载完成之后,但在BeanFactoryPostProcessor执行之前执行。 在所有BeanDefinition都已经注册完成,但还没有实例化任何 bean 之前执行。 典型应用场景 实现动态注册 bean,例如 MyBatis 的MapperScannerConfigurer;自定义注解扫描。 修改 bean 的定义属性,比如PropertySourcesPlaceholderConfigurer。 3.2 执行原理 - 源码分析
核心入口:AbstractApplicationContext.refresh() 中的 invokeBeanFactoryPostProcessors(beanFactory) 方法。以下是关键逻辑的源码解析:
1. 源码逻辑概览
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // 【本次主角】调用在上下文中注册的BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource();
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. *
Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 。。。 }
2. 核心处理逻辑(源码注释版)
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) { // 【 1. 处理所有 BeanDefinitionRegistryPostProcessor(子接口)】 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new LinkedList(); List registryPostProcessors = new LinkedList(); // 分阶段处理:PriorityOrdered → Ordered → 普通实现 // 执行 PriorityOrdered invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // 执行 Ordered invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // 执行 普通实现 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 。。。 // 【 2. 处理所有 BeanFactoryPostProcessor】 // 分阶段处理:PriorityOrdered → Ordered → 普通实现 List priorityOrderedPostProcessors = new ArrayList(); List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 执行 PriorityOrdered invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 执行 Ordered invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 执行 普通实现 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 。。。 }
具体执行方法:invokeBeanFactoryPostProcessors
/** * Invoke the given BeanFactoryPostProcessor beans. */ private static void invokeBeanFactoryPostProcessors( Collection
- 使用BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor 的子接口)扩展注册能力