接上文,Bean的屬性裝配前2:SmartInstantiationAwareBeanPostProcessor
回到doCreateBean方法,把單例對象緩存到第三級緩存之后,開始對這個Bean進(jìn)行屬性填充,來到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一次機(jī)會在屬性注入前修改Bean的狀態(tài)
// 具體通過調(diào)用postProcessAfterInstantiation方法,
// 如果調(diào)用返回false,表示不必繼續(xù)進(jìn)行依賴注入,直接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp
= (InstantiationAwareBeanPostProcessor) bp;
// 從這里可以得到結(jié)論,一旦對某個bean進(jìn)行屬性裝配的時候,執(zhí)行此處的后置回調(diào)方法
// 一旦某個回調(diào)返回false,那么continueWithPropertyPopulation被賦值為false
// 后續(xù)Spring就不會為這個bean進(jìn)行屬性填充
if (!ibp.postProcessAfterInstantiation(
bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation返回false
// 則不進(jìn)行后續(xù)的屬性填充操作,包括自動裝配和@Autowired屬性注入
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 根據(jù)Bean配置的自動裝配模式完成注入,默認(rèn)是0,即不走以下邏輯
// 如果設(shè)置了相關(guān)的依賴裝配方式,會遍歷Bean中的屬性
// 根據(jù)類型或名稱來完成相應(yīng)注入,無需額外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME
|| mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根據(jù)名稱自動裝配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根據(jù)類型自動裝配
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) {
// 檢查是否滿足相關(guān)依賴關(guān)系,對應(yīng)的depends-on屬性,
// 需要確保所有依賴的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 將pvs上所有的屬性填充到BeanWrapper對應(yīng)的Bean實例中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在這里,我們又看到了熟悉的InstantiationAwareBeanPostProcessor后置處理器,在Bean的實例化過程中,Spring借助它的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation在一個Bean實例化之前回調(diào)判斷是否需要為Bean生成代理對象(Bean實例化1:InstantiationAwareBeanPostProcessor),此處Spring則是利用它的InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation回調(diào)處理,簡單的來看下這個借口的定義,它繼承了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通過構(gòu)造器或者工廠方法實例化之后,在Spring為這個Bean裝配屬性之前調(diào)用
* 這是在Spring自動注入屬性之前,為指定bean進(jìn)行自定義屬性注入的最理想回調(diào)時機(jī)
* 結(jié)合populateBean屬性裝配方法,可以看到,當(dāng)這個方法返回false的時候,
* 其實就是告訴Spring這個bean不需要進(jìn)行屬性裝配
*/
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;
}
}
總結(jié):
Spring在為bean進(jìn)行屬性填充的時候,提供了一個擴(kuò)展點InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,利用此擴(kuò)展點,可以決定某個bean是否交由Spring進(jìn)行屬性填充