BeanFactoryPostProcessor 后置处理器的执行顺序

本文详细阐述了Spring中BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的执行顺序和优先级。BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法优先级最高,其次是实现PriorityOrdered和Ordered接口的后置处理器,最后是未实现排序接口的。BeanFactoryPostProcessor的执行顺序同样遵循这一规律。理解这些执行顺序对于理解和优化Spring应用的初始化过程至关重要。

BeanFactoryPostProcessor有两种形式被spring执行,优先级不相同

BeanDefinitionRegistryPostProcessor(对应BeanDefinitionRegistry接口,管理bean元数据)实现了BeanFactoryPostProcessor接口
#postProcessBeanDefinitionRegistry(自己独有的方法)
#postProcessBeanFactory(BeanFactoryPostProcessor的方法)
BeanFactoryPostProcessor(对应BeanFactory接口,管理bean对象)
#postProcessBeanFactory
注:会不会执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry还需要看BeanFactory实现类是否实现BeanDefinitionRegistry,没有实现则不执行

执行顺序,优先级由高到低依次为:

  1. BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(spring 直接new出来的后置处理器,没有交给容器管理的)
  2. BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(自定义的实现类,并实现PriorityOrdered接口,同等级还会进行排序)
  3. BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(自定义的实现类,并实现Ordered接口,同等级还会进行排序)
  4. BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(自定义的实现类)
  5. BeanDefinitionRegistryPostProcessor#postProcessBeanFactory(因为在前面1,2,3,4步的时候,已经排序放入一个list了,所以这里按1,2,3,4步的顺序执行后置处理器)
    ====================================上面BeanDefinitionRegistryPostProcessor
    ====================================下面BeanFactoryPostProcessor
  6. BeanFactoryPostProcessor#postProcessBeanFactory(spring 直接new出来的后置处理器,没有交给容器管理的)
  7. BeanFactoryPostProcessor#postProcessBeanFactory(实现PriorityOrdered接口,同等级还会进行排序)
  8. BeanFactoryPostProcessor#postProcessBeanFactory(实现Ordered接口,同等级还会进行排序)
  9. BeanFactoryPostProcessor#postProcessBeanFactory

如果只看自定义的后置处理器的执行顺序,由高到低依次为:

  1. BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
  2. BeanDefinitionRegistryPostProcessor#postProcessBeanFactory
  3. BeanFactoryPostProcessor#postProcessBeanFactory
    注:同种类型的后置处理器,实现PriorityOrdered接口的优先级高于实现Ordered接口的,没有实现排序接口的优先级最低
这里补充一点BeanPostProcessor的坑(BeanPostProcessor与上面一样,都是使用PriorityOrdered/Ordered实现优先级的)

结论:BeanPostProcessor不会处理优先级大于等于的BeanPostProcessor
1、实现PriorityOrdered,不会被BeanPostProcessor处理
因为此时BeanFactory中没有BeanPostProcessor,所以在getBean的时候,不会经过BeanPostProcessor处理
当都实例化结束,会注册到BeanFactory,供getBean时使用(只包含PriorityOrdered2、实现Ordered,只会被实现PriorityOrderedBeanPostProcessor处理
因为此时BeanFactory中只有实现PriorityOrderedBeanPostProcessor,所以在getBean的时候,被这部分BeanPostProcessor处理
当都实例化结束,会注册到BeanFactory,供getBean时使用(包含PriorityOrdered/Ordered3、没有实现PriorityOrderedOrdered,会被实现PriorityOrderedBeanPostProcessor处理
因为此时BeanFactory中包含了指定优先级的BeanPostProcessor,所以在getBean的时候,被指定优先级的BeanPostProcessor处理
当都实例化结束,会注册到BeanFactory,供getBean时使用(包含PriorityOrdered/Ordered,还有没有指定优先级的BeanPostProcessor4、后面通过getBean,就会被所有BeanPostProcessor处理了

例子:
AOP是通过AbstractAutoProxyCreator实现的,该类实现了BeanPostProcessor,同时也通过Ordered实现优先级(AOP的后置处理器是最低优先级的)
在AbstractAutoProxyCreator中有一个interceptorNames属性,可以对所有AOP代理类再加一层切面,但是需要手动对这个属性设置值
自定义BeanPostProcessor,同时也通过Ordered指定高优先级,发现interceptorNames为空,也就是不生效,后面更改为PriorityOrdered,interceptorNames有值了

具体执行顺序看PostProcessorRegistrationDelegate 类

final class PostProcessorRegistrationDelegate {
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		//存储自定义的BeanDefinitionRegistryPostProcessors 实现类
		//并且是已经执行过postProcessBeanFactory方法的
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//存储spring容器直接new出来的BeanFactoryPostProcessor(没有给容器管理)
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			//存储spring容器直接new出来的BeanDefinitionRegistryPostProcessor(没有给容器管理)
			//还有存储用户自定义的BeanDefinitionRegistryPostProcessor(交给容器管理的)
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//对spring容器直接new出来的BeanFactoryPostProcessor(没有给容器管理)进行分类
			//按是否实现BeanDefinitionRegistryPostProcessor
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//执行BeanDefinitionRegistryPostProcessor自己独有的方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			//存储当前要执行BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法的后置处理器
			//即实现PriorityOrdered接口的存入list,统一执行后,清空list
			//然后实现Ordered接口的存入list,统一执行后,清空list
			//最后将剩下的存入list,统一执行后,清空list
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// 获取容器中所有自定义的BeanDefinitionRegistryPostProcessor实现类
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			//处理实现PriorityOrdered接口的后置处理器
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//按优先级排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//registryProcessors是为了优先执行postProcessBeanDefinitionRegistry,后面统一执行postProcessBeanFactory,下同
			registryProcessors.addAll(currentRegistryProcessors);
			//执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			//处理实现Ordered接口的后置处理器
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			//这个方法就是执行currentRegistryProcessors中所有
			//BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			boolean reiterate = true;//控制是否执行完所有的BeanDefinitionRegistryPostProcessor
/*
上面已经获取了BeanDefinitionRegistryPostProcessor的所有实现类了,这儿又循环获取的原因:
在执行了postProcessBeanDefinitionRegistry之后,可能会重新再注册BeanDefinitionRegistryPostProcessor
的实现类进来,新注册的还没被执行,所以需要继续getBeanNamesForType,再重复之前的动作,
直到getBeanNamesForType不到值为止,这时候就确保了所有的BeanDefinitionRegistryPostProcessor实现类
都被执行了
*/
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}
/*====================
上面的逻辑,主要是获取BeanDefinitionRegistryPostProcessor的所有实现类,
并确保每个实现类都会执行自己的方法postProcessBeanDefinitionRegistry
下面再统一执行postProcessBeanFactory
=========================
*/
			//优先执行BeanDefinitionRegistryPostProcessor的实现类(new出来和自定义的)
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			//再执行BeanFactoryPostProcessor的实现类(new出来的)
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			//BeanFactory实现类没有实现BeanDefinitionRegistry接口,则将
			//BeanDefinitionRegistryPostProcessor当普通的BeanFactoryPostProcessor执行
			//不会执行其特有的方法
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
/*===========================
上面执行的直接new出来的BeanFactoryPostProcessor
以及BeanDefinitionRegistryPostProcessor
================================*/
		//获取自定义的BeanFactoryPostProcessor实现类名称(由IOC容器管理的)
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
		//按优先级分类存储后置处理器
		//优先级高
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//优先级中
		List<String> orderedPostProcessorNames = new ArrayList<>();
		//优先级低
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		//按优先级对后置处理器进行分类
		for (String ppName : postProcessorNames) {
			//processedBeans存的是自定义的BeanDefinitionRegistryPostProcessor实现类(优先级最高)
			//因为在上面流程已经执行过了,所以这儿忽略
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			//判断BeanFactoryPostProcessor实现类的优先级,放入各自匹配的集合中
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				//根据bean名称从IOC容器中获取实现类
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		//实现PriorityOrdered接口的优先执行,需要按配置的级别排序先后执行
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		//根据bean名称去IOC容器获取实现类
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		//实现Ordered的次之
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		//根据bean名称去IOC容器获取实现类
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		//最后执行普通的
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}
}
### Java Bean 后置处理器的功能与作用 #### 功能概述 Java Bean后置处理器(`BeanPostProcessor`)是在Spring框架中用于自定义容器管理的bean实例化后的行为。此类处理器允许开发者在特定阶段介入并修改或增强bean的行为。具体来说,`BeanPostProcessor`提供了两个主要的方法:`postProcessBeforeInitialization()` 和 `postProcessAfterInitialization()`. 前者会在任何显式的初始化回调(比如InitializingBean接口中的afterPropertiesSet方法或是通过init-method属性指定的方法调用前被触发;后者则在其之后执行。 对于`postProcessBeforeInitialization(Object bean, String beanName)`而言,此方法提供了一个机会去操作新创建出来的但是尚未完成其生命周期内其他配置步骤的对象实例[^4]。这使得开发人员能够在实际业务逻辑启动之前对这些对象施加影响——例如设置额外属性、注册监听器或者是像AOP那样动态地为某些类生成代理实例以便拦截目标方法调用。 而当涉及到`postProcessAfterInitialization(Object bean, String beanName)`时,则意味着此时所有的标准初始化过程都已经结束,并且如果存在的话,Aware接口的相关注入也已经发生过了。因此在这个时刻所做的更改通常是为了响应那些依赖于完全构建好的上下文环境的任务,如缓存预热或者其他形式的状态同步工作。 值得注意的是,在整个Spring应用程序上下文中,不同类型的后置处理器有着严格的加载顺序:首先是`BeanDefinitionRegistryPostProcessor`,接着才是普通的`BeanFactoryPostProcessor`最后才轮到`BeanPostProcessor`发挥作用[^1]. #### 应用场景举例 为了更好地理解如何利用`BeanPostProcessor`来解决问题,下面给出几个典型的应用案例: - **面向切面编程(AOP)**: 如前所述,借助`BeanPostProcessor`可以在不改变原有代码结构的前提下轻松实现横切关注点分离的目的。例如,想要给某个服务层组件增加日志记录功能而不必直接编辑源码文件,就可以考虑在此处为其包裹一层装饰模式下的代理对象。 - **性能优化**: 对象池技术是一种常见的提高系统吞吐量的方式之一。假设有一个频繁使用的资源需要反复创建销毁,那么完全可以编写专门针对该类型bean的工厂后置处理器,在每次请求到来之际从预先准备好的集合里取出可用实体供临时使用,从而减少不必要的开销。 - **安全控制**: 当面临复杂的权限验证需求时,也可以尝试运用这种方式来进行细粒度访问限制。即每当有新的控制器实例诞生之时自动附加相应的过滤机制进去,确保只有经过授权的操作才能被执行下去。 ```java // 示例代码展示简单的BeanPostProcessor实现 @Component public class MyCustomBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { System.out.println("Processing before initialization of " + beanName); return bean; // 可以在这里返回一个新的或修改过的bean实例 } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("Processing after initialization of " + beanName); return bean; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值