Sping源码(八)—registerBeanPostProcessors

序言

之前我们用大量的篇幅介绍过invokeBeanFactoryPostProcessors()方法的执行流程。

invokeBeanFactoryPostProcessors的主要逻辑就是遍历执行实现了BeanDefinitionRegistryPostProcesso类(主要是针对BeanDefinition的操作)和BeanFactoryPostProcessor(主要针对BeanFacroty的操作)

我们这篇文章里要介绍的registerBeanPostProcessors()方法 和 invokeBeanFactoryPostProcessors()方法类似,作用对象是Bean,用于在 Spring 容器实例化、配置和初始化 bean 的过程中提供自定义的扩展点。

源码

获取系统中实现BeanPostProcessor的类并进行分类,添加到BeanFacroty中。处理逻辑和BeanPosrProcessor基本相似。

java 复制代码
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		//获取所有实现了BeanPostProcessor类的BeanName
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.

		//这里的 +1,应该是为了为下方的 new BeanPostProcessorChecker 留个位置
		//创建的BeanPostProcessorChecker是用来
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.

		//用来存放实现riorityOrdered的BeanPostProcessor
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//用来存放实现MergedBeanDefinitionPostProcessor的BeanPostProcessor
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		//用来存放实现Ordered的BeanPostProcessor
		List<String> orderedPostProcessorNames = new ArrayList<>();
		//用来存放没有实现排序接口的BeanPostProcessor
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();

		//遍历获取所有的BeanPostProcessor
		for (String ppName : postProcessorNames) {
			//判断是否实现了PriorityOrdered接口
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				//获取BeanPostProcessor
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				//判断是否实现了MergedBeanDefinitionPostProcessor接口
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			//如果实现了Ordered接口,则添加到orderedPostProcessorNames中
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				//否则就是没有实现排序接口的类
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.

		//根据优先级进行排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		//注册(循环添加到BeanFactory的beanPostProcessors集合中)实现priorityOrder接口的BeanPostProcessor
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.

		//注册(循环添加到BeanFactory的beanPostProcessors集合中)实现Ordered接口的BeanPostProcessor
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		//最后注册(循环添加到BeanFactory的beanPostProcessors集合中)没有实现排序接口的BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.

		//重新注册(循环添加到BeanFactory的beanPostProcessors集合中)实现MergedBeanDefinitionPostProcessor接口的BeanPostProcessor
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).

		//注册ApplicationListenerDetector,
		// 其实refresh()主流程方法下的prepareBeanFactory(beanFactory)方法中已经向beanFactory中添加了ApplicationListenerDetector
		//这里是重新注册,保证ApplicationListenerDetector在beanPostProcessors集合的最后
		//目的是检测并管理应用程序上下文中的事件监听器。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

扩展

值得说的地方是Spirng提供了几个比较重要的BeanPostProcessor接口可以用来进行扩展。因为其与四个接口都继承自BeanPostProcessor所以BeanPostProcessor中的方法他们也都有。

挨个接口来看看里面都有什么。

BeanPostProcessor

bean的后置处理器接口,在依赖注入的初始化方法前后进行调用。

java 复制代码
/**
 * bean的后置处理器接口,在依赖注入的初始化方法前后进行调用
 */
public interface BeanPostProcessor {

	/**
	 * 初始化方法调用前要进行的处理逻辑
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * 在初始化方法指定后要进行的处理逻辑
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

InstantiationAwareBeanPostProcessor

新增了属性注入的方法。

java 复制代码
/**
 * 继承自BeanPostProcessor,添加了实例化前,实例化后,属性注入后的处理方法
 */
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	//省略BeanPostProcessor方法...

	/**
	 * 当使用注解的时候,通过这个方法来完成属性的注入
	 */
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	/**
	 * 属性注入后执行的方法,在5.1版本被废弃
	 */
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}

SmartInstantiationAwareBeanPostProcessor

继承自InstantiationAwareBeanPostProcessor ,额外增加3个方法。

java 复制代码
/**
 * 继承自InstantiationAwareBeanPostProcessor接口,增加了三个额外处理的方法,由spring内部使用
 *
 */
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

	/**
	 * 预测bean的类型,主要是在bean还没有创建前我们需要获取bean的类型
	 *
	 */
	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	/**
	 * 完成对构造函数的解析和推断
	 */
	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {

		return null;
	}

	/**
	 * 解决循环依赖问题,通过此方法提前暴露一个合格的对象
	 *
	 */
	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

MergedBeanDefinitionPostProcessor

两个BeanDefinition合并时调用。

java 复制代码
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

	/**
	 *spring通过此方法找出所有需要注入的字段,同时做缓存
	 */
	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

	/**
	 * 用于在BeanDefinition被修改后,清除容器的缓存
	 */
	default void resetBeanDefinition(String beanName) {
	}
}

DestructionAwareBeanPostProcessor

判断Bean是否应该销毁和销毁时调用

java 复制代码
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

	/**
	 * 在bean被销毁前调用
	 */
	void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

	/**
	 * 判断是否要进行销毁,一般情况下都需要
	 */
	default boolean requiresDestruction(Object bean) {
		return true;
	}
}
相关推荐
虫小宝12 分钟前
如何在Java中实现PDF生成
java·开发语言·pdf
菜鸡且互啄691 小时前
在线教育平台,easyexcel使用案例
java·开发语言
八月林城1 小时前
JAVA导出数据库字典到Excel
java·数据库·excel
浅念同学3 小时前
算法-常见数据结构设计
java·数据结构·算法
杰哥在此5 小时前
Java面试题:讨论持续集成/持续部署的重要性,并描述如何在项目中实施CI/CD流程
java·开发语言·python·面试·编程
咖啡煮码6 小时前
深入剖析Tomcat(十五、十六) 关闭钩子,保证Tomcat的正常关闭
java·tomcat
C.C6 小时前
java IO流(1)
java·开发语言
黑头!7 小时前
Tomcat注册为服务之后 运行时提示JVM异常
java·jvm·tomcat
袁震8 小时前
Java---Mybatis详解二
java·开发语言·mybatis
《黑巧克力》8 小时前
【JavaEE】多线程进阶
java·spring·java-ee·maven·dubbo·idea