前置說明:
一、類與接口繼承關系: public abstract class AbstractAutowireCapableBeanFactory
extends AbstractBeanFactory implements AutowireCapableBeanFactory
二、本文章說明的是單例、并且是第一次執行個體化,同時不涉及其他複雜情況産生Bean用以說明Spring産生一個簡單Bean單例的過程。用以說明在Bean執行個體化過程中對BeanPostProcessor/InitializingBean/Aware接口的調用順序
1、通過beanName擷取Bean
類AbstractBeanFactory的方法: doGetBean(String name, @Nullable Class<T> requiredType,
@Nullable Object[] args, boolean typeCheckOnly);
如果類還沒有建立并且是單例、類建立的實作:
if(mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
mbd即為RootBeanDefinition實作的是BeanDefinition接口,BeanDefinition接口對應的就是在spring配置檔案配置的Bean
即:
<bean id="car" name="car1" class="com.fev.Car"></bean>
this.getSingleton方法的知識點有單例三層緩存解決循環依賴,以及Lambda表達式,為了本文說明知識點的單一,暫時不展開說明,可搜尋其他博文。
直接進入this.createBean(beanName, mbd, args)方法,就進入類AbstractAutowireCapableBeanFactory
在此方法調用真正執行個體化bean的方法-this.doCreateBean(beanName, mbdToUse, args);
Bean執行個體化一個空對象的代碼為
BeanWrapper instanceWrapper = null;
if(instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
這些代碼就是将(beanName, mbd, args)這些參數建構一個BeanWrapper .并産生一個空的Bean對象
之後就是通過方法this.populateBean(beanName, mbd, instanceWrapper)填充Bean的屬性
debug運作此方法前
運作此方法後:
之後進入方法this.initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd);此方法為BeanPostProcessor/InitializingBean/Aware這三個接口的具體調用順序:
源碼:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if(System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if(mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", var6);
}
if(mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
由此可見,首先是運作Aware接口的方法this.invokeAwareMethods(beanName, bean);
之後通過方法 this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);運作BeanPostProcessor的postProcessBeforeInitialization方法
源碼:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Object current;
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor processor = (BeanPostProcessor)var4.next();
current = processor.postProcessBeforeInitialization(result, beanName);
if(current == null) {
return result;
}
}
return result;
}
然後運作方法this.invokeInitMethods(beanName, wrappedBean, mbd);執行InitializingBean接口的afterPropertiesSet方法.
源碼:
boolean isInitializingBean = bean instanceof InitializingBean;
if(isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if(this.logger.isTraceEnabled()) {
this.logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if(System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(() -> {
((InitializingBean)bean).afterPropertiesSet();
return null;
}, this.getAccessControlContext());
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
((InitializingBean)bean).afterPropertiesSet();
}
}
最後通過方法wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
運作BeanPostProcessor接口的postProcessAfterInitialization(result, beanName)方法。
由此可見,這三個接口的調用順序是Aware接口->BeanPostProcessor接口的postProcessBeforeInitialization方法->InitializingBean接口的afterPropertiesSet方法->BeanPostProcessor接口的postProcessAfterInitialization方法。
最後提一下的是:由BeanPostProcessor、InitializingBean接口的使用也可以知道,BeanPostProcessor接口是對你注入的所有Bean都有作用,而InitializingBea。Aware是對你實作了這個接口的Bean起作用