轉(zhuǎn)載自個(gè)人博客https://chenjiabing666.github.io/2019/06/25/InstantiationAwareBeanPostProcessor%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/
簡(jiǎn)介
- 繼承
BeanPostProcessor
接口脯倚,在此基礎(chǔ)上又定義了三個(gè)方法,分別在Bean實(shí)例化前后【不是初始化】執(zhí)行屎慢。 - 從上面的介紹可以看到慷妙,這個(gè)接口相對(duì)于BeanPostProcessor功能更加強(qiáng)大宏所,一個(gè)接口承擔(dān)了Bean的實(shí)例化前后、初始化前后責(zé)任诈铛。
Bean加載順序
- ioc容器創(chuàng)建加載Bean的執(zhí)行順序如下:
- InstantiationAwareBeanPostProcessor接口中的
postProcessBeforeInstantiation
,在實(shí)例化之前調(diào)用 - Bean的實(shí)例化墨礁,調(diào)用構(gòu)造方法
- InstantiationAwareBeanPostProcessor接口中的
postProcessAfterInstantiation
,在實(shí)例化之后調(diào)用 - InstantiationAwareBeanPostProcessor接口中的
postProcessPropertyValues
【當(dāng)postProcessAfterInstantiation返回true才執(zhí)行】 - BeanPostProcessor接口中的
postProcessBeforeInitialization
耳峦,在初始化之前調(diào)用 - InitializingBean中的afterProperties方法恩静,執(zhí)行初始化
- BeanPostProcessor接口中的
postProcessAfterInitialization
,在實(shí)例化之后調(diào)用
- InstantiationAwareBeanPostProcessor接口中的
InstantiationAwareBeanPostProcessor接口方法的執(zhí)行順序
- 正常的執(zhí)行順序如下:
- postProcessBeforeInstantiation
- postProcessAfterInstantiation
- postProcessProperties
- postProcessBeforeInitialization
- postProcessAfterInitialization
方法解析
-
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
:在實(shí)例化之前執(zhí)行【構(gòu)造方法之前執(zhí)行】- 返回值:如果返回的不為
null
蹲坷,那么后續(xù)的Bean的創(chuàng)建流程【實(shí)例化驶乾、初始化afterProperties】都不會(huì)執(zhí)行,而是直接使用返回的快捷Bean循签,此時(shí)的正常執(zhí)行順序如下:- InstantiationAwareBeanPostProcessor接口中的
postProcessBeforeInstantiation
级乐,在實(shí)例化之前調(diào)用 - BeanPostProcessor接口中的
postProcessAfterInitialization
,在實(shí)例化之后調(diào)用
- InstantiationAwareBeanPostProcessor接口中的
- 返回值:如果返回的不為
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation
* 作用:在實(shí)例化之前解析是否有快捷創(chuàng)建的Bean县匠,既是通過(guò)postProcessBeforeInstantiation返回的Bean
* 內(nèi)部調(diào)用兩個(gè)重要的方法:
* 1风科、applyBeanPostProcessorsBeforeInstantiation:內(nèi)部遍歷調(diào)用postProcessBeforeInstantiation方法【在實(shí)例化之前調(diào)用】
* 2、applyBeanPostProcessorsAfterInitialization:如果postProcessBeforeInstantiation方法返回了快捷的Bean乞旦,內(nèi)部遍歷調(diào)用postProcessBeforeInstantiation方法【在初始化之后調(diào)用】
*/
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) {
//調(diào)用方法贼穆,內(nèi)部遍歷調(diào)用postProcessBeforeInstantiation方法【在實(shí)例化之前調(diào)用】
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果返回了快捷的Bean
if (bean != null) {
//如果postProcessBeforeInstantiation方法返回了快捷的Bean,內(nèi)部遍歷調(diào)用postProcessBeforeInstantiation方法【在初始化之后調(diào)用】
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation
* 作用:調(diào)用postProcessBeforeInstantiation方法
*/
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
//遍歷所有的后置處理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判斷是否是InstantiationAwareBeanPostProcessor類(lèi)型的兰粉,如果是的故痊,調(diào)用postProcessBeforeInstantiation方法獲取快捷Bean
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization
* 作用:遍歷調(diào)用postProcessAfterInitialization
*/
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
-
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException
:正常情況下在實(shí)例化之后在執(zhí)行populateBean
之前調(diào)用- 返回值:如果有指定的bean的時(shí)候返回false,那么后續(xù)的屬性填充和屬性依賴注入【
populateBean
】將不會(huì)執(zhí)行玖姑,同時(shí)后續(xù)的postProcessPropertyValues
將不會(huì)執(zhí)行,但是初始化和BeanPostProcessor
的仍然會(huì)執(zhí)行愕秫。
- 返回值:如果有指定的bean的時(shí)候返回false,那么后續(xù)的屬性填充和屬性依賴注入【
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean
* 填充指定Bean的屬性
* 在該方法內(nèi)部遍歷所有的BeanPostPorcessor,調(diào)用postProcessAfterInstantiation方法
*/
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;
}
}
//**********************邏輯開(kāi)始執(zhí)行********************
//標(biāo)志焰络,判斷是否繼續(xù)執(zhí)行屬性填充戴甩,默認(rèn)為false
boolean continueWithPropertyPopulation = true;
//判斷ioc容器中是否存在InstantiationAwareBeanPostProcessors(
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//遍歷所有的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判斷類(lèi)型是InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//執(zhí)行postProcessAfterInstantiation方法
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
//返回結(jié)果為false,那么賦值continueWithPropertyPopulation=false舔琅,表示不繼續(xù)執(zhí)行屬性填充
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果continueWithPropertyPopulation為false等恐,直接返回,不執(zhí)行下面的步驟
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) {
//同樣是遍歷BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//執(zhí)行postProcessPropertyValues方法
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//重要的一步备蚓,設(shè)置屬性
applyPropertyValues(beanName, mbd, bw, pvs);
}
-
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
:實(shí)例化之后調(diào)用课蔬,在方法applyPropertyValues
【屬性填充】之前- 返回值:如果返回null,那么將不會(huì)進(jìn)行后續(xù)的屬性填充郊尝,比如依賴注入等二跋,如果返回的pvs額外的添加了屬性,那么后續(xù)會(huì)填充到該類(lèi)對(duì)應(yīng)的屬性中流昏。
- pvs:PropertyValues對(duì)象扎即,用于封裝指定類(lèi)的對(duì)象吞获,簡(jiǎn)單來(lái)說(shuō)就是PropertyValue的集合,里面相當(dāng)于以key-value形式存放類(lèi)的屬性和值
- pds:PropertyDescriptor對(duì)象數(shù)組谚鄙,PropertyDescriptor相當(dāng)于存儲(chǔ)類(lèi)的屬性各拷,不過(guò)可以調(diào)用set,get方法設(shè)置和獲取對(duì)應(yīng)屬性的值
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean的代碼片段
*/
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
//遍歷調(diào)用postProcessPropertyValues方法
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
//如果返回的pvs是null闷营,直接返回
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//執(zhí)行真正的屬性填充
applyPropertyValues(beanName, mbd, bw, pvs);
實(shí)例
- 只是寫(xiě)了
InstantiationAwareBeanPostProcessor
定義的方法烤黍,另外的BeanPostProcessor
的方法,請(qǐng)看上一篇文章
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
* 在實(shí)例化之前調(diào)用傻盟,如果返回null速蕊,一切按照正常順序執(zhí)行,如果返回的是一個(gè)實(shí)例的對(duì)象娘赴,那么這個(gè)將會(huì)跳過(guò)實(shí)例化规哲、初始化的過(guò)程
* @param beanClass
* @param beanName
* @return
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass == User.class) {
System.out.println("postProcessBeforeInstantiation執(zhí)行");
return null;
}
return null;
}
/**
* 在實(shí)例化之后,postProcessBeforeInitialization之前執(zhí)行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean instanceof User) {
System.out.println("postProcessAfterInstantiation執(zhí)行");
return true;
}
return true;
}
/**
* 實(shí)例化之后調(diào)用诽表,屬性填充之前
* @param pvs PropertyValues對(duì)象唉锌,用于封裝指定類(lèi)的對(duì)象,簡(jiǎn)單來(lái)說(shuō)就是PropertyValue的集合关顷,里面相當(dāng)于以key-value形式存放類(lèi)的屬性和值
* @param pds PropertyDescriptor對(duì)象數(shù)組糊秆,PropertyDescriptor相當(dāng)于存儲(chǔ)類(lèi)的屬性,不過(guò)可以調(diào)用set议双,get方法設(shè)置和獲取對(duì)應(yīng)屬性的值
* @param bean 當(dāng)前的bean
* @param beanName beanName
* @return 如果返回null痘番,那么將不會(huì)進(jìn)行后續(xù)的屬性填充,比如依賴注入等平痰,如果返回的pvs額外的添加了屬性汞舱,那么后續(xù)會(huì)填充到該類(lèi)對(duì)應(yīng)的屬性中。
*/
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if (pvs instanceof MutablePropertyValues&&bean instanceof User){
MutablePropertyValues mutablePropertyValues= (MutablePropertyValues) pvs;
HashMap<Object, Object> map = new HashMap<>();
map.put("name","陳加兵");
map.put("age",44);
mutablePropertyValues.addPropertyValues(map);
return mutablePropertyValues;
}
/**使用pds設(shè)置值
if (bean instanceof User) {
for (PropertyDescriptor descriptor:pds) {
try {
if ("name".equals(descriptor.getName())) {
descriptor.getWriteMethod().invoke(bean, "陳加兵");
}else if("age".equals(descriptor.getName())){
descriptor.getWriteMethod().invoke(bean,40);
}
}catch (Exception e){
e.printStackTrace();
}
}
return null;
}**/
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof User) {
System.out.println("postProcessBeforeInitialization執(zhí)行");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof User) {
System.out.println("postProcessAfterInitialization執(zhí)行");
}
return bean;
}
}
源碼梳理
- 無(wú)論是BeanPostProcessor還是
InstantiationAwareBeanPostProcessor
都是在對(duì)象實(shí)例化和初始化前后執(zhí)行的邏輯宗雇,因此我們主要的代碼都在getBean
昂芜,doGetBean
,cerateBean
方法中 -
BeanPostProcessor
的兩個(gè)方法的執(zhí)行源碼請(qǐng)看上一篇的文章 - 步驟如下:
- [圖片上傳失敗...(image-4658b9-1561472145733)]
- [圖片上傳失敗...(image-824031-1561472145733)]
- [圖片上傳失敗...(image-b7d4b0-1561472145733)]
- [圖片上傳失敗...(image-d4fb2f-1561472145733)]
- [圖片上傳失敗...(image-1ad844-1561472145733)]
- [圖片上傳失敗...(image-40efd3-1561472145733)]
- [圖片上傳失敗...(image-cd78c-1561472145733)]
- [圖片上傳失敗...(image-2b40a-1561472145733)]
- [圖片上傳失敗...(image-acc5c5-1561472145733)]
Autowired源碼解析
- 從源碼可以看出赔蒲,Autowired的功能實(shí)現(xiàn)最重要的一個(gè)接口就是
AutowiredAnnotationBeanPostProcessor
泌神,繼承關(guān)系如下:
[圖片上傳失敗...(image-518665-1561472145733)] - 從繼承關(guān)系圖可以看出,實(shí)際上關(guān)鍵的實(shí)現(xiàn)了
InstantiationAwareBeanPostProcessor
這個(gè)接口舞虱。 - 源碼實(shí)現(xiàn)如下圖:
[圖片上傳失敗...(image-f8c9e8-1561472145733)]
總結(jié)
- 源碼:
- ioc容器創(chuàng)建Bean的方法是從
createBean
方法進(jìn)入的欢际,真正執(zhí)行創(chuàng)建的Bean的是doCreateBean
方法,我們從createBean開(kāi)始往下走- 調(diào)用
resolveBeforeInstantiation
方法【在doCreatBean之前執(zhí)行矾兜,即是實(shí)例化之前】损趋,在內(nèi)部遍歷BeanPostProcessor調(diào)用postProcessBeforeInstantiation
方法 - 如果
postProcessBeforeInstantiation
方法返回null,那么需要執(zhí)行實(shí)例化的過(guò)程椅寺,調(diào)用doCreatBean
實(shí)例化Bean浑槽。-
doCreateBean
內(nèi)部分為兩步:①調(diào)用createBeanInstance實(shí)例化Bean蒋失;②調(diào)用populateBean
設(shè)置Bean的屬性
-
- 在
populateBean
內(nèi)部分為如下的步驟:- 調(diào)用
postProcessAfterInstantiation
【實(shí)例化之后調(diào)用】,分為兩種情況:①返回false桐玻,后續(xù)的postProcessPropertyValues
將不再執(zhí)行篙挽,屬性也不在進(jìn)行設(shè)置;②返回true畸冲,程序照常進(jìn)行嫉髓,調(diào)用postProcessPropertyValues
,屬性設(shè)置的過(guò)程正常進(jìn)行
- 調(diào)用
- 執(zhí)行完
populateBean
之后將會(huì)調(diào)用initializeBean
【初始化Bean邑闲,調(diào)用afterPropertiesSet方法】,在內(nèi)部就涉及到BeanPostProcessor定義的接口了梧油,步驟如下:- 執(zhí)行
applyBeanPostProcessorsBeforeInitialization
方法調(diào)用postProcessBeforeInitialization
【在初始化之前調(diào)用】方法 - 執(zhí)行
invokeInitMethods
方法苫耸,內(nèi)部其實(shí)是調(diào)用afterPropeertiesSet方法,進(jìn)行初始化 - 執(zhí)行
applyBeanPostProcessorsAfterInitialization
儡陨,內(nèi)部調(diào)用postProcessAfterInitialization
【在實(shí)例化之后調(diào)用】方法
- 執(zhí)行
- 調(diào)用
- ioc容器創(chuàng)建Bean的方法是從