接上文,Bean的属性装配前2:SmartInstantiationAwareBeanPostProcessor
回到doCreateBean
方法,把单例对象缓存到第三级缓存之后,开始对这个Bean进行属性填充,来到populateBean
方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
// ...
// Initialize the bean instance.
// 开始初始化Bean
Object exposedObject = bean;
try {
// 此处开始为一个Bean的属性赋值
populateBean(beanName, mbd, instanceWrapper);
// Bean的初始化过程,可见在属性赋值之后,后面会讨论这个过程
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException
&& beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName,
"Initialization of bean failed", ex);
}
}
// ...
}
/**
* 为Bean的属性赋值的核心方法
*/
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 {
// 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.
// 给InstantiationAwareBeanPostProcessors一次机会在属性注入前修改Bean的状态
// 具体通过调用postProcessAfterInstantiation方法,
// 如果调用返回false,表示不必继续进行依赖注入,直接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp
= (InstantiationAwareBeanPostProcessor) bp;
// 从这里可以得到结论,一旦对某个bean进行属性装配的时候,执行此处的后置回调方法
// 一旦某个回调返回false,那么continueWithPropertyPopulation被赋值为false
// 后续Spring就不会为这个bean进行属性填充
if (!ibp.postProcessAfterInstantiation(
bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation返回false
// 则不进行后续的属性填充操作,包括自动装配和@Autowired属性注入
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根据Bean配置的自动装配模式完成注入,默认是0,即不走以下逻辑
// 如果设置了相关的依赖装配方式,会遍历Bean中的属性
// 根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME
|| mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型自动装配
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) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
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) {
// 检查是否满足相关依赖关系,对应的depends-on属性,
// 需要确保所有依赖的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在这里,我们又看到了熟悉的InstantiationAwareBeanPostProcessor
后置处理器,在Bean的实例化过程中,Spring借助它的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
在一个Bean实例化之前回调判断是否需要为Bean生成代理对象(Bean实例化1:InstantiationAwareBeanPostProcessor),此处Spring则是利用它的InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
回调处理,简单的来看下这个借口的定义,它继承了BeanPostProcessor
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* Perform operations after the bean has been instantiated, via a constructor or factory method,
* but before Spring property population (from explicit properties or autowiring) occurs.
* <p>This is the ideal callback for performing custom field injection on the given bean
* instance, right before Spring's autowiring kicks in.
* <p>The default implementation returns {@code true}.
*
* 在一个bean通过构造器或者工厂方法实例化之后,在Spring为这个Bean装配属性之前调用
* 这是在Spring自动注入属性之前,为指定bean进行自定义属性注入的最理想回调时机
* 结合populateBean属性装配方法,可以看到,当这个方法返回false的时候,
* 其实就是告诉Spring这个bean不需要进行属性装配
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName)
throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
return pvs;
}
}
总结:
Spring在为bean进行属性填充的时候,提供了一个扩展点InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
,利用此扩展点,可以决定某个bean是否交由Spring进行属性填充