Spring BeanFactoryPostProcessor:机制解读与代码实践

06-01 1334阅读

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 的典型实现?

              Spring 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的区别

                对比维度BeanFactoryPostProcessorBeanPostProcessor
                操作对象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。(稍后会有源码解析)

                      主要差异

                      对比维度BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor
                      核心作用能够对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
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码