Spring后置处理器中的InstantiationAwareBeanPostProcessor详解

其是BeanPostProcessor的子接口,增加了before-instantiation回调,以及在postProcessAfterInstantiation(bean实例化后但是确切属性设置/autowire注入发生)前增加了postProcessAfterInstantiation回调。

通常用于抑制特定目标bean的默认实例化,例如AbstractAutoProxyCreator创建具有特殊TargetSources的代理(池目标、延迟初始化目标等),或实现其他注入策略,如字段注入。

接口源码

我们看一下接口源码与方法说明。如下所示接口的四个方法均有默认实现。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	@Nullable
	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;
	}
}

postProcessBeforeInstantiation

在目标bean开始实例化前触发该方法。返回的bean对象可能是要使用的代理,而不是目标bean,从而有效地抑制了目标bean的默认实例化。如果此方法返回非null对象,则bean创建过程将被短路(也就是正常bean实例化的后续流程不再执行)。

此callback将应用于bean定义及其bean类,以及工厂方法定义,在这种情况下,返回的bean类型将在此处传递。后置处理器可以实现继承SmartInstantiationAwareBeanPostProcessor接口,以预测它们将在此处返回的bean对象的类型。

该方法将会返回要暴露的bean对象,而不是目标bean的默认实例,如果返回 null 继续默认实例化流程。

如下图所示,其在AbstractAutowireCapableBeanFactory的createBean方法创建Bean实例时被触发。
在这里插入图片描述

//AbstractAutowireCapableBeanFactory
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				// 前置方法-尝试获取一个代理对象
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
				// 后置方法 判断是否应该给bean设置属性还是跳过属性设置
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

在这里插入图片描述

应用实例

AbstractAutoProxyCreatorpostProcessBeforeInstantiation方法,将会尝试创建一个代理对象返回。如果这里返回的Bean不为null,那么将不会再执行Object beanInstance = doCreateBean(beanName, mbdToUse, args);方法。

在这里插入图片描述


postProcessAfterInstantiation

在bean被实例化之后,通过构造函数或工厂方法,但在Spring属性填充(from explicit properties or autowiring)发生之前,执行操作。

这是在Spring的自动连接开始之前,在给定bean实例上执行自定义字段注入的理想回调。

当然返回结果为true时,说明应该为bean设置属性。如果返回结果为false,跳过bean属性赋值环节。

默认实现返回true。

在AbstractAutowireCapableBeanFactory的populateBean方法中我们同样可以看到该方法的触发。
在这里插入图片描述


postProcessProperties

在工厂将给定的属性值应用于给定的bean之前,对其进行后处理,而不需要任何属性描述符。

如果实现类提供自定义的{postProcessPropertyValues}实现,则应返回{ null}(默认值),否则返回{ pvs}。

在这个接口的未来版本中(删除了{postprocesspropertyvalue}),默认实现将直接返回给定的{ pvs}。

这个方法很重要哦,因为AutowiredAnnotationBeanPostProcessor就是InstantiationAwareBeanPostProcessor,其继承于InstantiationAwareBeanPostProcessorAdapter。在Bean实例化过程中,会在populateBean触发该方法的回调,其将会解析依赖(如 @Autowired SysFileService fileService;)。
在这里插入图片描述
以AutowiredAnnotationBeanPostProcessor为例,其postProcessProperties方法如下所示。可以看到其将会获取使用了@Autowired字段和方法,触发依赖的解析。

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
	InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
	try {
		metadata.inject(bean, beanName, pvs);
	}
	catch (BeanCreationException ex) {
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
	}
	return pvs;
}

postProcessPropertyValues

与postProcessProperties方法不同的是,该方法多了参数属性描述符(PropertyDescriptor[])。在上图我们也可以看到,如果执行完postProcessProperties后pvsToUse仍旧为null,那么就会触发postProcessPropertyValues方法。

在DefaultListableBeanFactory将给定属性值应用于给定bean之前,对其进行后处理。允许检查是否满足了所有依赖项,例如基于bean属性设置器上的“Required”注解。

还允许替换要应用的属性值,通常是基于原始PropertyValues实例创建新的MutablePropertyValues 实例,添加或删除特定值。

默认返回PropertyValues pvs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值