Spring系列 BeanPostProcessor

文章目录


本文源码基于spring-beans-5.3.31

参考:https://docs.spring.io/spring-framework/reference/core/beans/factory-extension.html#beans-factory-extension-bpp


BeanPostProcessor 是 Spring 框架中的一个接口,用于在 bean 实例化和初始化过程中进行一些回调处理,可以对Bean进行一些扩展或修改。

BeanPostProcessor

注册时机

AbstractApplicationContext#refresh里进行注册。此时所有Bean的配置信息都已解析并加载完毕

注册时并未区分BeanPostProcessor具体是什么类型

java 复制代码
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

AbstractBeanFactory维护了一个BeanPostProcessor列表,保存所有注册的 BeanPostProcessor

同时针对后期的使用提供了BeanPostProcessorCache这个类,用于缓存不同类型的BeanPostProcessor,从而进行不同的处理逻辑

通过懒加载策略进行初始化

java 复制代码
BeanPostProcessorCache getBeanPostProcessorCache() {
	synchronized (this.beanPostProcessors) {
		BeanPostProcessorCache bppCache = this.beanPostProcessorCache;
		if (bppCache == null) {
			bppCache = new BeanPostProcessorCache();
			// 区分不同的实现类型,放到对应的list集合中
			for (BeanPostProcessor bpp : this.beanPostProcessors) {
				if (bpp instanceof InstantiationAwareBeanPostProcessor) {
					bppCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bpp);
					if (bpp instanceof SmartInstantiationAwareBeanPostProcessor) {
						bppCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bpp);
					}
				}
				if (bpp instanceof DestructionAwareBeanPostProcessor) {
					bppCache.destructionAware.add((DestructionAwareBeanPostProcessor) bpp);
				}
				if (bpp instanceof MergedBeanDefinitionPostProcessor) {
					bppCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bpp);
				}
			}
			this.beanPostProcessorCache = bppCache;
		}
		return bppCache;
	}
}

执行时机

BeanPostProcessor提供了Bean的生命周期的一些回调操作,所以它的执行是伴随着Bean的生命周期执行而执行的

InstantiationAwareBeanPostProcessor

org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor扩展了 BeanPostProcessor,用于在 bean 实例化和初始化过程中进行更细粒度的处理。

java 复制代码
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
		return null;
	}

	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		return pvs;
	}
}

它提供了多个方法,下面是各个方法的作用

  1. postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
    在 bean 实例化之前调用。可以用于检查 bean 的元数据,决定是否需要实例化该 bean,或者返回一个替代的实例。可以返回一个替代的 bean 实例,或者返回 null 继续正常的实例化流程。
  1. postProcessAfterInstantiation(Object bean, String beanName)
    在 bean 实例化之后调用,可以用于逻辑处理,比如检查 bean 是否需要进行某些初始化操作。通常返回 true,表示允许继续进行属性填充。如果返回 false,则 Spring 将跳过属性的设置。
  1. postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    在填充 bean 属性之前调用,用于处理 PropertyValues。可以修改属性值或条件性地填充属性。
    参数pvs 是待填充的属性值,bean 是当前的 bean 实例,beanName 是 bean 的名称。返回修改后的 PropertyValues,或者返回原始的 pvs。
  1. postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)

由于继承了BeanPostProcessor,所以postProcessBeforeInitialization(Object bean, String beanName)和postProcessAfterInitialization(Object bean, String beanName)这两个方法和BeanPostProcessor一致

SmartInstantiationAwareBeanPostProcessor

java 复制代码
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

	@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;
	}
}
  1. Class<?> predictBeanType(Class<?> beanClass, String beanName)
  1. Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
  1. Object getEarlyBeanReference(Object bean, String beanName)

在 bean 实例化后、初始化之前调用,允许返回早期的 bean 引用。这可以解决循环依赖问题,特别是在需要提前获取 bean 的情况下。返回早期的 bean 实例,或原始的 bean(即不做任何更改)。

相关推荐
kokunka4 分钟前
C#类修饰符功能与范围详解
java·开发语言·c#
仟濹16 分钟前
【Java 基础】3 面向对象 - this
java·开发语言·python
radient20 分钟前
Agent的"思考" - 智能体
后端·架构·ai编程
百***355126 分钟前
什么是Spring Boot 应用开发?
java·spring boot·后端
梅花1444 分钟前
基于Django的博客系统
后端·python·django·毕业设计·博客·博客系统·毕设
謝堆堆DDD1 小时前
eclipse由只运行java文件到创建web项目
java·ide·eclipse
redtro951 小时前
【开发备忘】GeoServer相关两则:发布时间维ImageMosaic+客户端WMS样式
java·开发语言·spring
代码不停1 小时前
Java模拟算法题目练习
java·开发语言·算法
百***26631 小时前
Tomcat的server.xml配置详解
xml·java·tomcat
Hilaku1 小时前
我为什么说全栈正在杀死前端?
前端·javascript·后端