概念
談論到實例化處理器和初始化處理器,我們要明確一個實例化和初始化概念,大牛們可以忽略此處說明。
- 實例化:指創建類實例(對象)的過程。比如使用構造方法new對象,爲對象在內存中分配空間。(要創建對象,但是並未生成對象)
- 初始化:指爲類中各個類成員(被static修飾的成員變量)賦初始值的過程,是類生命週期中的一個階段。簡單理解爲對象中的屬性賦值的過程。(對象已經生成,爲其屬性賦值)
源碼
從源碼解讀實例化處理器和初始化處理器。
- InstantiationAwareBeanPostProcessor
該接口繼承自BeanPostProcessor接口,並自定義如圖方法。
- postProcessBeforeInstantiation 實例化前置處理 (對象未生成)
- postProcessAfterInstantiation 實例化後置處理 (對象已經生成)
- postProcessPropertyValues 修改屬性值。(對象已經生成)
- BeanPostProcessor
- postProcessBeforeInitialization初始化前置處理 (對象已經生成)
- postProcessAfterInitialization初始化後置處理 (對象已經生成)
觸發處理器時機
從Bean的生命週期流程中可知,實例化和初始化處理器作用時機主要在初始化Bean前後。
主要在類AbstractAutowireCapableBeanFactory中
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//根據設置的class屬性或者根據className來解析class:調用AbstractBeanFactory類
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//驗證以及準備覆蓋的方法即Override方法
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//返回代理來代替真正的實例:--------------應用實例化前的前置處理器
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//短路操作,返回bean
if (bean != null) {
//返回bean的代理對象
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//---------------創建單例bean對象:核心方法doCreateBean(常規bean的創建過程)
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
- 觸發postProcessBeforeInstantiation時機
postProcessBeforeInstantiation調用時機: BeanDefinition創建Bean的開端是在createBean()方法也就是流水線的開始處。
注意是否返回bean的代理對象,如果返回Bean的代理對象,則直接return代理對象;即resolveBeforeInstantiation()方法,源代碼如下
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//是否實現前置處理器接口
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//調用InstantiationAwareBeanPostProcessor:實例化前置處理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//調用初始化後置處理器,doCreateBean流程結束
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
解釋說明:
- 首先,判斷是否存在InstantiationAwareBeanPostProcessor接口的處理器
- 如存在,則調用的是InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()實例化前置處理方法,也就是在Bean對象沒有生成之前執行(實例化過程中)。(注意:這裏所說的是Bean未生成指的是Bean沒有走spring定義創建Bean的流程,也就是doCreateBean()方法。)
- 如果postProcessBeforeInstantiation()返回的對象不爲空, 意味着Bean對象已經存在,表明對象已經初始化完成。然後調用postProcessAfterInitialization()初始化後置處理器,完成對Bean對象的操作.
如果postProcessBeforeInstantiation()返回值爲空,則進入上層調用者createBean()方法,繼續調用doCreateBean()方法,完成對象實例化(創建對象),以及對象初始化.
- postProcessAfterInstantiation調用時機
上面createBean()方法中標識若resolveBeforeInstantiation()方法沒有返回bean,則調用doCreateBean()方法,進入創建bean流程中;
下面我們開始分析doCreateBean()的部分代碼
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
...//省略部分源碼
// Initialize the bean instance.
//------------------------完成實例化bean創建,下面開始進行------bean初始化操作-------------
Object exposedObject = bean;
try {
//----****屬性填充操作:其中可能會存在依賴其他bean屬性,則會遞歸初始化依賴bean****
populateBean(beanName, mbd, instanceWrapper);
//--- ****初始化指定的bean實例*****,回調init()方法和執行處理器
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);
}
}
...//省略後面代碼
}
跟蹤populateBean()方法的源碼實現,便可以發現postProcessAfterInstantiation() 與postProcessPropertyValues()依次被執行。該方法仍然處於實例化過程。
...省略部分源碼
//是否實現InstantiationAwareBeanPostProcessor接口,以及bean是否依賴檢查
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
//處理實現了InstantiationAwareBeanPostProcessor
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//一次調用實現的InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
- postProcessBeforeInitialization、 postProcessAfterInitialization
初始化前後處理器,從initializeBean()方法中依次被調用執行
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//如果bean是BeanNameAware,BeanClassLoaderAware或者BeanFactoryAware其中某一個的實現類就需要進行處理
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//bean生命週期之一:如果實現了BeanPostProcessor接口,則會在此調用實現類中的beanPostProcessorsBeforeInitialization()方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//bean生命週期之一:如果實現InitializingBean接口,則會在此調用實現類中的afterPropertiesSet()方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//bean生命週期之一:如果實現了BeanPostProcessor接口,則會在此調用實現類中的beanPostProcessorAfterInitialization()方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
總結
- BeanPostProcessor定義的方法是在對象初始化過程中做處理,分別在resolveBeforeInstantiation()觸發後置處理器,或者在initializeBean依次調用前後處理器。
- InstantiationAwareBeanPostProcessor定義的方法是在對象實例化過程中做處理,即分別在resolveBeforeInstantiation()、populateBean()觸發前置處理器,後置處理器。
從上面分析可知:
實例化—>初始化過程中會形成兩條路徑。
- postProcessBeforeInstantiation()–自定義對象–>postProcessAfterInitialization();
- postProcessBeforeInstantiation() -->postProcessAfterInstantiation–>postProcessBeforeInitialization()–>postProcessAfterInitialization()
postProcessBeforeInstantiation一定執行, postProcessAfterInitialization一定執行.
參考資料:https://juejin.im/post/5da995d25188256a49204d7b