在深入学习Spring Bean生命周期一节中,我们学习了Bean后置处理器BeanPostProcessor,用于在Bean初始化前后插入我们自己的逻辑(Bean增强,Bean代理等)。但是你知道BeanPostProcessor的子类InstantiationAwareBeanPostProcessor吗?他用于Bean实例化前后处理。
本节记录两者的区别以及简单原理分析。
1. 两者比较
Initialization为初始化的意思,Instantiation为实例化的意思。在Spring Bean生命周期中,实例化指的是创建Bean的过程,初始化指的是Bean创建后,对其属性进行赋值(populate bean)、后置处理等操作的过程,所以Instantiation执行时机先于Initialization。
1.1 类关系
先来看看BeanPostProcessor的类结构:
public interface BeanPostProcessor {
// bean 初始化之前执行
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// bean 初始化之后执行
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
InstantiationAwareBeanPostProcessor为BeanPostProcessor的子类,新增了三个额外的方法:
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;
}
}
1.2 方法解析
- BeanPostProcessor
postProcessBeforeInitialization(Object bean, String beanName)
:bean:Bean实例;beanName:Bean名称。方法将在Bean实例的afterPropertiesSet方法或者自定义的init方法被调用前调用,此时Bean属性已经被赋值。方法返回原始Bean实例或者包装后的Bean实例,如果返回null,则后续的后置处理方法不再被调用。postProcessAfterInitialization(Object bean, String beanName)
:bean:Bean实例;beanName:Bean名称。方法将在Bean实例的afterPropertiesSet方法或者自定义的init方法被调用后调用,此时Bean属性已经被赋值。方法返回原始Bean实例或者包装后的Bean实例,如果返回null,则后续的后置处理方法不再被调用。
- InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
:beanClass:待实例化的Bean类型;beanName:待实例化的Bean名称。方法作用为:在Bean实例化前调用该方法,返回值可以为代理后的Bean,以此代替Bean默认的实例化过程。返回值不为null时,后续只会调用BeanPostProcessor的 postProcessAfterInitialization方法,而不会调用别的后续后置处理方法(如postProcessAfterInitialization、postProcessBeforeInstantiation等方法);返回值也可以为null,这时候Bean将按默认方式初始化。postProcessAfterInstantiation(Object bean, String beanName)
:bean:实例化后的Bean,此时属性还没有被赋值;beanName:Bean名称。方法作用为:当Bean通过构造器或者工厂方法被实例化后,当属性还未被赋值前,该方法会被调用,一般用于自定义属性赋值。方法返回值为布尔类型,返回true时,表示Bean属性需要被赋值;返回false表示跳过Bean属性赋值,并且InstantiationAwareBeanPostProcessor的postProcessProperties方法不会被调用。
1.3 执行时机对比
为了验证实例化和初始化的先后顺序,我们直接新建一个SpringBoot项目测试即可(我这里还使用之前的老项目):
Spring入口类名称为SpringDemoApplication
。新建MyBeanPostProcessor
实现BeanPostProcessor接口:
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("springDemoApplication".equals(beanName)) {
System.out.println("post processor before " + beanName + " initialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("springDemoApplication".equals(beanName)) {
System.out.println("post processor after " + beanName + " initialization");
}
return bean;
}
}
因为对所有的Bean生效,所以为了方便观察输出,这里仅当Bean名称为springDemoApplication
时才打印输出。
注册进容器中:
@Bean
public MyBeanPostProcessor myBeanPostProcessor () {
return new MyBeanPostProcessor();
}
接着新建MyBeanInstantiationPostProcessor
实现InstantiationAwareBeanPostProcessor接口:
public class MyBeanInstantiationPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("springDemoApplication".equals(beanName)) {
System.out.println("post process before " + beanName + " instantiation");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("springDemoApplication".equals(beanName)) {
System.out.println("post process after " + beanName + " instantiation");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("springDemoApplication".equals(beanName)) {
System.out.println("post process " + beanName + " properties");
}
return pvs;
}
}
记得配置到webconfig里面。
@Bean
public MyBeanInstantiationPostProcessor myBeanInstantiationPostProcessor() {
return new MyBeanInstantiationPostProcessor();
}
启动程序,输出如下所示:
如果将MyBeanInstantiationPostProcessor的postProcessAfterInstantiation方法返回值改为false,程序输出如下:
2. 原理解析
postProcessAfterInitialization和InstantiationAwareBeanPostProcessor的方法都和Bean生命周期有关,要分析它们的实现原理自然要从Bean的创建过程入手。Bean创建的入口为AbstractAutowireCapableBeanFactory
的createBean方法,查看其源码:
resolveBeforeInstantiation
方法给Bean后置处理器一个返回目标Bean实例代理的机会,所以我们先重点关注下这个方法的源码。
该方法先于下面的doCreateBean
方法,也就是说里面的操作逻辑实在Bean实例化之前完成的。
resolveBeforeInstantiation
方法源码如下所示:
相关注释直接标记在代码中,方便查看。
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//beforeInstantiationResolved默认属性值为false,表示Bean实例化前置操作未执行
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//判断是否有InstantiationAwareBeanPostProcessors处理器
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = this.determineTargetType(beanName, mbd);
//有的话执行PostProcessorsBeforeInstantiation方法
if (targetType != null) {
bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果上述方法返回值不为null,则说明Bean已经在该方法中实例化了(代理,增加),那么直接执行BeanPostProcessor的PostProcessorsAfterInitialization方法
if (bean != null) {
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//如果Bean不为null,则将beforeInstantiationResolved属性值设置true
mbd.beforeInstantiationResolved = bean != null;
}
return bean;
}
上面方法返回的bean如果为空的话,AbstractAutowireCapableBeanFactory
的createBean方法将继续往下执行doCreateBean方法:
查看doCreateBean方法源码:
这个时候我们会发现这里源码很多,我们先不看其他部分(Bean生命周期其他部分),重点关注populateBean和initializeBean方法。查看populateBean方法源码:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessors().iterator();
while(var4.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var4.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
//这个地方需要注意,当返回值为false的时候,直接返回,后续赋值操作不执行了
return;
}
}
}
}
// begin 这一块为属性赋值,aotowired,通过类型或者名称注入
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//end
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//属性赋值后,判断是否有InstantiationAwareBeanPostProcessor实例,有的话从缓存集合中获取遍历
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
//逐个调用其postProcessProperties方法
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//逐个调用其postProcessPropertyValues方法
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
接着查看initializeBean方法源码:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行PostProcessorsBeforeInitialization
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
//执行PostProcessorsAfterInitialization
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
至此我们通过查看Bean生命周期相关源码弄清楚了BeanPostProcessor和InstantiationAwareBeanPostProcessor相关方法的执行时机以及原理。
上面源码的追踪其实不仅涉及到了BeanPostProcessor和InstantiationAwareBeanPostProcessor相关方法的执行时机以及原理,更是整个Bean生命周期创建过程。
3. 总结
下面通过一张流程图总结本文: