Bean建立過程當中的「實例化」與「初始化」名詞spring
BeanPostProcessor : 發生在 BeanDefiniton 加工Bean 階段. 具備攔截器的含義. 能夠攔截BeanDefinition建立Bean的過程, 而後插入攔截方法,作擴展工做.app
InstantiationAwareBeanPostProcessor: 繼承於BeanPostProcessor ,因此他也是一種參與BeanDefinition加工Bean過程的BeanPostProcessor攔截器, 而且豐富了BeanPostProcessor的攔截.ide
總的來講:post
BeanPostProcessor定義的方法是在對象初始化過程當中作處理。 InstantiationAwareBeanPostProcessor定義的方法是在對象實例化過程當中作處理this
1.postProcessBeforeInstantiation 調用時機: BeanDefinition建立Bean的開端是在createBean()方法也就是流水線的開始處。spa
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
...省略
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
複製代碼
看這段英文註釋: Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.debug
給BeanPostProcessor一個機會去返回一個代理對象. 就是在流水線doCreateBean()生成對象以前, 給用戶自定義返回一個對象的機會.設計
再看看resolveBeforeInstantiation(beanName, mbdToUse)是如何處理自定義返回對象的.代理
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調用時機code
上文resolveBeforeInstantiation()沒有返回bean.則走流水線建立Bean
doCreateBean(beanName, mbdToUse, args)建立對象,會通過**populateBean(beanName, mbd, instanceWrapper)**方法。
populateBean(beanName, mbd, instanceWrapper)依次執行postProcessAfterInstantiation() 與postProcessPropertyValues()
3.postProcessBeforeInitialization調用時機
doCreateBean(beanName, mbdToUse, args)建立對象,會通過**initializeBean(beanName, exposedObject, mbd);**方法。
initializeBean(beanName, exposedObject, mbd); 會首先執行 **postProcessBeforeInitialization()**方法
4.postProcessAfterInitialization
initializeBean(beanName, exposedObject, mbd); 會首先執行 **postProcessAfterInitialization()**方法
實例化--->初始化
會造成兩種執行流程完成BeanDefinition 建立Bean.
咱們看出:postProcessBeforeInstantiation必定執行, postProcessAfterInitialization必定執行.
至此:不知道讀者是否體會到了InstantiationAwareBeanPostProcessor與BeanPostProcessor接口 以及其定義的4個方法的妙處.
四個方法執行的順序對理解spring建立流程有着重要意義。
BeanPostProcessor 自己就是一種攔截的設計思想. 攔截的目的就是作額外的操做, 即 擴展。
歡迎你們關注個人公衆號【源碼行動】,最新我的理解及時奉送。