我们知道bean在spring中有两个大的状态。实例化,初始化;那么在bean成长过程中我们是不是可以进行干预,或者进行观察呢?自己生的孩子不可能都不管不问吧。所以在bean成长的各个环节中我们都有办法去干预,或者收到通知。spring通过暴露几个接口的方式来赋予你这个能力;
我要实例化了-> 实例化 做点啥 属性赋值 做点啥 做点啥 初始化 再做点啥
今天的主角
是BeanPostProcessor;作用是一个勾子,也就是一个回调函数,在bean创建的各个阶段进行回调
看下长什么样子先
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
在bean初始化 前后会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization
该接口执行逻辑在doCreateBean中调用的initializeBean里面;绝大部分的BeanPostProcessor都是在这里执行调用的。也有特殊。先看大部分的:
路标: applyBeanPostProcessorsBeforeInitialization,和applyBeanPostProcessorsAfterInitialization就是在执行初始化方法invokeInitMethods之前和之后调用
BeanPostProcessor用的;
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
特殊情况是InstantiationAwareBeanPostProcessor; 是postProcessor的一个子类
比postProcessor多了三个接口
接口 | 作用 |
---|---|
postProcessBeforeInitialization | 初始化前 |
postProcessAfterInitializationpost | 初始化后调用 |
ProcessBeforeInstantiation | 实例化之前调用 |
postProcessAfterInstantiation | 实例化之后调用 |
postProcessPropertyValues | 属性赋值后回调 |
初始化前后上面看过了。下面看另外三个。
1.实例化前
源码位置在:createBean->resolveBeforeInstantiation
**路标:applyBeanPostProcessorsBeforeInstantiation **
注意:这里如果用户自己实例化bean并且返回了。那么后面由spring创建bean的逻辑就会不执行。直接执行applyBeanPostProcessorsAfterInitialization逻辑,也就是直接执行初始化成功回调。另外的实例化后和属性赋值后逻辑都不会执行了。为什么呢?你喵的都自己创建对象了,那么属性赋值肯定是你自己搞定了。也就是说实例化和属性赋值都是你自己弄得,那生命周期你自己都知道了自己加逻辑就是了。就没必要再绕一圈让spring通知你了。就像是你自己干了一件事,然后还让别人告诉你你干了啥?你干了啥你自己心里没数吗?
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 = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
2:实例化后
实例化之后逻辑:postProcessAfterInstantiation
位置在populateBean中InstantiationAwareBeanPostProcessor注意这里调用该接口如果返回false则会中断属性赋值继续往下执行
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}