從篇章一到這里是一個(gè)分水嶺,前面的內(nèi)容都還算比較簡(jiǎn)單,大家要清楚地知道前面都做了哪些事情。
Bean 容器實(shí)例化完成后
說(shuō)到這里,我們回到 refresh() 方法,我重新貼了一遍代碼,看看我們說(shuō)到哪了。是的,我們才說(shuō)完 obtainFreshBeanFactory() 方法。
考慮到篇幅,這里開(kāi)始大幅縮減掉沒(méi)必要詳細(xì)介紹的部分,大家直接看下面的代碼中的注釋就好了。
@Override
public void refresh() throws BeansException, IllegalStateException {
// 來(lái)個(gè)鎖,不然 refresh() 還沒(méi)結(jié)束,你又來(lái)個(gè)啟動(dòng)或銷毀容器的操作,那不就亂套了嘛
synchronized (this.startupShutdownMonitor) {
// 準(zhǔn)備工作,記錄下容器的啟動(dòng)時(shí)間、標(biāo)記“已啟動(dòng)”狀態(tài)、處理配置文件中的占位符
prepareRefresh();
// 這步比較關(guān)鍵,這步完成后,配置文件就會(huì)解析成一個(gè)個(gè) Bean 定義,注冊(cè)到 BeanFactory 中,
// 當(dāng)然,這里說(shuō)的 Bean 還沒(méi)有初始化,只是配置信息都提取出來(lái)了,
// 注冊(cè)也只是將這些信息都保存到了注冊(cè)中心(說(shuō)到底核心是一個(gè) beanName-> beanDefinition 的 map)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 設(shè)置 BeanFactory 的類加載器,添加幾個(gè) BeanPostProcessor,手動(dòng)注冊(cè)幾個(gè)特殊的 bean
// 這塊待會(huì)會(huì)展開(kāi)說(shuō)
prepareBeanFactory(beanFactory);
try {
// 【這里需要知道 BeanFactoryPostProcessor 這個(gè)知識(shí)點(diǎn),Bean 如果實(shí)現(xiàn)了此接口,
// 那么在容器初始化以后,Spring 會(huì)負(fù)責(zé)調(diào)用里面的 postProcessBeanFactory 方法。】
// 這里是提供給子類的擴(kuò)展點(diǎn),到這里的時(shí)候,所有的 Bean 都加載、注冊(cè)完成了,但是都還沒(méi)有初始化
// 具體的子類可以在這步的時(shí)候添加一些特殊的 BeanFactoryPostProcessor 的實(shí)現(xiàn)類或做點(diǎn)什么事
postProcessBeanFactory(beanFactory);
// 調(diào)用 BeanFactoryPostProcessor 各個(gè)實(shí)現(xiàn)類的 postProcessBeanFactory(factory) 回調(diào)方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊(cè) BeanPostProcessor 的實(shí)現(xiàn)類,注意看和 BeanFactoryPostProcessor 的區(qū)別
// 此接口兩個(gè)方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 兩個(gè)方法分別在 Bean 初始化之前和初始化之后得到執(zhí)行。這里僅僅是注冊(cè),之后會(huì)看到回調(diào)這兩方法的時(shí)機(jī)
registerBeanPostProcessors(beanFactory);
// 初始化當(dāng)前 ApplicationContext 的 MessageSource,國(guó)際化這里就不展開(kāi)說(shuō)了,不然沒(méi)完沒(méi)了了
initMessageSource();
// 初始化當(dāng)前 ApplicationContext 的事件廣播器,這里也不展開(kāi)了
initApplicationEventMulticaster();
// 從方法名就可以知道,典型的模板方法(鉤子方法),不展開(kāi)說(shuō)
// 具體的子類可以在這里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
onRefresh();
// 注冊(cè)事件監(jiān)聽(tīng)器,監(jiān)聽(tīng)器需要實(shí)現(xiàn) ApplicationListener 接口。這也不是我們的重點(diǎn),過(guò)
registerListeners();
// 重點(diǎn),重點(diǎn),重點(diǎn)
// 初始化所有的 singleton beans
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 最后,廣播事件,ApplicationContext 初始化完成,不展開(kāi)
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 銷毀已經(jīng)初始化的 singleton 的 Beans,以免有些 bean 會(huì)一直占用資源
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// 把異常往外拋
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
準(zhǔn)備 Bean 容器: prepareBeanFactory
之前我們說(shuō)過(guò),Spring 把我們?cè)?xml 配置的 bean 都注冊(cè)以后,會(huì)"手動(dòng)"注冊(cè)一些特殊的 bean。
這里簡(jiǎn)單介紹下 prepareBeanFactory(factory) 方法:
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 設(shè)置 BeanFactory 的類加載器,我們知道 BeanFactory 需要加載類,也就需要類加載器,
// 這里設(shè)置為加載當(dāng)前 ApplicationContext 類的類加載器
beanFactory.setBeanClassLoader(getClassLoader());
// 設(shè)置 BeanExpressionResolver
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一個(gè) BeanPostProcessor,這個(gè) processor 比較簡(jiǎn)單:
// 實(shí)現(xiàn)了 Aware 接口的 beans 在初始化的時(shí)候,這個(gè) processor 負(fù)責(zé)回調(diào),
// 這個(gè)我們很常用,如我們會(huì)為了獲取 ApplicationContext 而 implement ApplicationContextAware
// 注意:它不僅僅回調(diào) ApplicationContextAware,
// 還會(huì)負(fù)責(zé)回調(diào) EnvironmentAware、ResourceLoaderAware 等,看下源碼就清楚了
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 下面幾行的意思就是,如果某個(gè) bean 依賴于以下幾個(gè)接口的實(shí)現(xiàn)類,在自動(dòng)裝配的時(shí)候忽略它們,
// Spring 會(huì)通過(guò)其他方式來(lái)處理這些依賴。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
/**
* 下面幾行就是為特殊的幾個(gè) bean 賦值,如果有 bean 依賴了以下幾個(gè),會(huì)注入這邊相應(yīng)的值,
* 之前我們說(shuō)過(guò),"當(dāng)前 ApplicationContext 持有一個(gè) BeanFactory",這里解釋了第一行
* ApplicationContext 還繼承了 ResourceLoader、ApplicationEventPublisher、MessageSource
* 所以對(duì)于這幾個(gè)依賴,可以賦值為 this,注意 this 是一個(gè) ApplicationContext
* 那這里怎么沒(méi)看到為 MessageSource 賦值呢?那是因?yàn)?MessageSource 被注冊(cè)成為了一個(gè)普通的 bean
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 這個(gè) BeanPostProcessor 也很簡(jiǎn)單,在 bean 實(shí)例化后,如果是 ApplicationListener 的子類,
// 那么將其添加到 listener 列表中,可以理解成:注冊(cè) 事件監(jiān)聽(tīng)器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 這里涉及到特殊的 bean,名為:loadTimeWeaver,這不是我們的重點(diǎn),忽略它
// tips: ltw 是 AspectJ 的概念,指的是在運(yùn)行期進(jìn)行織入,這個(gè)和 Spring AOP 不一樣,
// 感興趣的讀者請(qǐng)參考我寫的關(guān)于 AspectJ 的另一篇文章 https://www.javadoop.com/post/aspectj
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
/**
* 從下面幾行代碼我們可以知道,Spring 往往很 "智能" 就是因?yàn)樗鼤?huì)幫我們默認(rèn)注冊(cè)一些有用的 bean,
* 我們也可以選擇覆蓋
*/
// 如果沒(méi)有定義 "environment" 這個(gè) bean,那么 Spring 會(huì) "手動(dòng)" 注冊(cè)一個(gè)
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 如果沒(méi)有定義 "systemProperties" 這個(gè) bean,那么 Spring 會(huì) "手動(dòng)" 注冊(cè)一個(gè)
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 如果沒(méi)有定義 "systemEnvironment" 這個(gè) bean,那么 Spring 會(huì) "手動(dòng)" 注冊(cè)一個(gè)
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
在上面這塊代碼中,Spring 對(duì)一些特殊的 bean 進(jìn)行了處理,讀者如果暫時(shí)還不能消化它們也沒(méi)有關(guān)系,慢慢往下看。
初始化所有的 singleton beans
我們的重點(diǎn)當(dāng)然是 finishBeanFactoryInitialization(beanFactory); 這個(gè)巨頭了,這里會(huì)負(fù)責(zé)初始化所有的 singleton beans。
注意,后面的描述中,我都會(huì)使用初始化或預(yù)初始化來(lái)代表這個(gè)階段,Spring 會(huì)在這個(gè)階段完成所有的 singleton beans 的實(shí)例化。
我們來(lái)總結(jié)一下,到目前為止,應(yīng)該說(shuō) BeanFactory 已經(jīng)創(chuàng)建完成,并且所有的實(shí)現(xiàn)了 BeanFactoryPostProcessor 接口的 Bean 都已經(jīng)初始化并且其中的 postProcessBeanFactory(factory) 方法已經(jīng)得到回調(diào)執(zhí)行了。而且 Spring 已經(jīng)“手動(dòng)”注冊(cè)了一些特殊的 Bean,如 ‘environment’、‘systemProperties’ 等。
剩下的就是初始化 singleton beans 了,我們知道它們是單例的,如果沒(méi)有設(shè)置懶加載,那么 Spring 會(huì)在接下來(lái)初始化所有的 singleton beans。
// AbstractApplicationContext.java 834
// 初始化剩余的 singleton beans
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 首先,初始化名字為 conversionService 的 Bean。本著送佛送到西的精神,我在附錄中簡(jiǎn)單介紹了一下 ConversionService,因?yàn)檫@實(shí)在太實(shí)用了
// 什么,看代碼這里沒(méi)有初始化 Bean ??!
// 注意了,初始化的動(dòng)作包裝在 beanFactory.getBean(...) 中,這里先不說(shuō)細(xì)節(jié),先往下看吧
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// 先初始化 LoadTimeWeaverAware 類型的 Bean
// 之前也說(shuō)過(guò),這是 AspectJ 相關(guān)的內(nèi)容,放心跳過(guò)吧
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// 沒(méi)什么別的目的,因?yàn)榈竭@一步的時(shí)候,Spring 已經(jīng)開(kāi)始預(yù)初始化 singleton beans 了,
// 肯定不希望這個(gè)時(shí)候還出現(xiàn) bean 定義解析、加載、注冊(cè)。
beanFactory.freezeConfiguration();
// 開(kāi)始初始化
beanFactory.preInstantiateSingletons();
}
從上面最后一行往里看,我們就又回到 DefaultListableBeanFactory 這個(gè)類了,這個(gè)類大家應(yīng)該都不陌生了吧。
preInstantiateSingletons
// DefaultListableBeanFactory 728
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// this.beanDefinitionNames 保存了所有的 beanNames
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 觸發(fā)所有的非懶加載的 singleton beans 的初始化操作
for (String beanName : beanNames) {
// 合并父 Bean 中的配置,注意 <bean id="" class="" parent="" /> 中的 parent,用的不多吧,
// 考慮到這可能會(huì)影響大家的理解,我在附錄中解釋了一下 "Bean 繼承",不了解的請(qǐng)到附錄中看一下
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、非懶加載的 singletons。如果配置了 'abstract = true',那是不需要初始化的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 處理 FactoryBean(讀者如果不熟悉 FactoryBean,請(qǐng)移步附錄區(qū)了解)
if (isFactoryBean(beanName)) {
// FactoryBean 的話,在 beanName 前面加上 ‘&’ 符號(hào)。再調(diào)用 getBean,getBean 方法別急
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
// 判斷當(dāng)前 FactoryBean 是否是 SmartFactoryBean 的實(shí)現(xiàn),此處忽略,直接跳過(guò)
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
// 對(duì)于普通的 Bean,只要調(diào)用 getBean(beanName) 這個(gè)方法就可以進(jìn)行初始化了
getBean(beanName);
}
}
}
// 到這里說(shuō)明所有的非懶加載的 singleton beans 已經(jīng)完成了初始化
// 如果我們定義的 bean 是實(shí)現(xiàn)了 SmartInitializingSingleton 接口的,那么在這里得到回調(diào),忽略
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
接下來(lái),我們就進(jìn)入到 getBean(beanName) 方法了,這個(gè)方法我們經(jīng)常用來(lái)從 BeanFactory 中獲取一個(gè) Bean,而初始化的過(guò)程也封裝到了這個(gè)方法里。
getBean
在繼續(xù)前進(jìn)之前,讀者應(yīng)該具備 FactoryBean 的知識(shí),如果讀者還不熟悉,請(qǐng)移步附錄部分了解 FactoryBean。
// AbstractBeanFactory 196
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// 我們?cè)谄饰龀跏蓟?Bean 的過(guò)程,但是 getBean 方法我們經(jīng)常是用來(lái)從容器中獲取 Bean 用的,注意切換思路,
// 已經(jīng)初始化過(guò)了就從容器中直接返回,否則就先初始化再返回
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 獲取一個(gè) “正統(tǒng)的” beanName,處理兩種情況,一個(gè)是前面說(shuō)的 FactoryBean(前面帶 ‘&’),
// 一個(gè)是別名問(wèn)題,因?yàn)檫@個(gè)方法是 getBean,獲取 Bean 用的,你要是傳一個(gè)別名進(jìn)來(lái),是完全可以的
final String beanName = transformedBeanName(name);
// 注意跟著這個(gè),這個(gè)是返回值
Object bean;
// 檢查下是不是已經(jīng)創(chuàng)建過(guò)了
Object sharedInstance = getSingleton(beanName);
// 這里說(shuō)下 args 唄,雖然看上去一點(diǎn)不重要。前面我們一路進(jìn)來(lái)的時(shí)候都是 getBean(beanName),
// 所以 args 傳參其實(shí)是 null 的,但是如果 args 不為空的時(shí)候,那么意味著調(diào)用方不是希望獲取 Bean,而是創(chuàng)建 Bean
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("...");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 下面這個(gè)方法:如果是普通 Bean 的話,直接返回 sharedInstance,
// 如果是 FactoryBean 的話,返回它創(chuàng)建的那個(gè)實(shí)例對(duì)象
// (FactoryBean 知識(shí),讀者若不清楚請(qǐng)移步附錄)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
// 創(chuàng)建過(guò)了此 beanName 的 prototype 類型的 bean,那么拋異常,
// 往往是因?yàn)橄萑肓搜h(huán)引用
throw new BeanCurrentlyInCreationException(beanName);
}
// 檢查一下這個(gè) BeanDefinition 在容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果當(dāng)前容器不存在這個(gè) BeanDefinition,試試父容器中有沒(méi)有
String nameToLookup = originalBeanName(name);
if (args != null) {
// 返回父容器的查詢結(jié)果
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// typeCheckOnly 為 false,將當(dāng)前 beanName 放入一個(gè) alreadyCreated 的 Set 集合中。
markBeanAsCreated(beanName);
}
/*
* 稍稍總結(jié)一下:
* 到這里的話,要準(zhǔn)備創(chuàng)建 Bean 了,對(duì)于 singleton 的 Bean 來(lái)說(shuō),容器中還沒(méi)創(chuàng)建過(guò)此 Bean;
* 對(duì)于 prototype 的 Bean 來(lái)說(shuō),本來(lái)就是要?jiǎng)?chuàng)建一個(gè)新的 Bean。
*/
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 先初始化依賴的所有 Bean,這個(gè)很好理解。
// 注意,這里的依賴指的是 depends-on 中定義的依賴
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 檢查是不是有循環(huán)依賴,這里的循環(huán)依賴和我們前面說(shuō)的循環(huán)依賴又不一樣,這里肯定是不允許出現(xiàn)的,不然要亂套了,讀者想一下就知道了
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注冊(cè)一下依賴關(guān)系
registerDependentBean(dep, beanName);
// 先初始化被依賴項(xiàng)
getBean(dep);
}
}
// 如果是 singleton scope 的,創(chuàng)建 singleton 的實(shí)例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 執(zhí)行創(chuàng)建 Bean,詳情后面再說(shuō)
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果是 prototype scope 的,創(chuàng)建 prototype 的實(shí)例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
// 執(zhí)行創(chuàng)建 Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 如果不是 singleton 和 prototype 的話,需要委托給相應(yīng)的實(shí)現(xiàn)類來(lái)處理
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
// 執(zhí)行創(chuàng)建 Bean
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 最后,檢查一下類型對(duì)不對(duì),不對(duì)的話就拋異常,對(duì)的話就返回了
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
大家應(yīng)該也猜到了,接下來(lái)當(dāng)然是分析 createBean 方法:
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException;
第三個(gè)參數(shù) args 數(shù)組代表創(chuàng)建實(shí)例需要的參數(shù),不就是給構(gòu)造方法用的參數(shù),或者是工廠 Bean 的參數(shù)嘛,不過(guò)要注意,在我們的初始化階段,args 是 null。
這回我們要到一個(gè)新的類了 AbstractAutowireCapableBeanFactory,看類名,AutowireCapable?類名是不是也說(shuō)明了點(diǎn)問(wèn)題了。
主要是為了以下場(chǎng)景,采用 @Autowired 注解注入屬性值:
public class MessageServiceImpl implements MessageService {
@Autowired
private UserService userService;
public String getMessage() {
return userService.getMessage();
}
}
<bean id="messageService" class="com.javadoop.example.MessageServiceImpl" />
以上這種屬于混用了 xml 和 注解 兩種方式的配置方式,Spring 會(huì)處理這種情況。
好了,讀者要知道這么回事就可以了,繼續(xù)向前。
// AbstractAutowireCapableBeanFactory 447
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 確保 BeanDefinition 中的 Class 被加載
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 準(zhǔn)備方法覆寫,這里又涉及到一個(gè)概念:MethodOverrides,它來(lái)自于 bean 定義中的 <lookup-method />
// 和 <replaced-method />,如果讀者感興趣,回到 bean 解析的地方看看對(duì)這兩個(gè)標(biāo)簽的解析。
// 我在附錄中也對(duì)這兩個(gè)標(biāo)簽的相關(guān)知識(shí)點(diǎn)進(jìn)行了介紹,讀者可以移步去看看
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 讓 InstantiationAwareBeanPostProcessor 在這一步有機(jī)會(huì)返回代理,
// 在 《Spring AOP 源碼分析》那篇文章中有解釋,這里先跳過(guò)
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);
}
// 重頭戲,創(chuàng)建 bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
創(chuàng)建 Bean
我們繼續(xù)往里看 doCreateBean 這個(gè)方法:
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 說(shuō)明不是 FactoryBean,這里實(shí)例化 Bean,這里非常關(guān)鍵,細(xì)節(jié)之后再說(shuō)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 這個(gè)就是 Bean 里面的 我們定義的類 的實(shí)例,很多地方我直接描述成 "bean 實(shí)例"
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
// 類型
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 建議跳過(guò)吧,涉及接口:MergedBeanDefinitionPostProcessor
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// MergedBeanDefinitionPostProcessor,這個(gè)我真不展開(kāi)說(shuō)了,直接跳過(guò)吧,很少用的
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 下面這塊代碼是為了解決循環(huán)依賴的問(wèn)題,以后有時(shí)間,我再對(duì)循環(huán)依賴這個(gè)問(wèn)題進(jìn)行解析吧
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 這一步也是非常關(guān)鍵的,這一步負(fù)責(zé)屬性裝配,因?yàn)榍懊娴膶?shí)例只是實(shí)例化了,并沒(méi)有設(shè)值,這里就是設(shè)值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 還記得 init-method 嗎?還有 InitializingBean 接口?還有 BeanPostProcessor 接口?
// 這里就是處理 bean 初始化完成后的各種回調(diào)
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);
}
}
if (earlySingletonExposure) {
//
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
到這里,我們已經(jīng)分析完了 doCreateBean 方法,總的來(lái)說(shuō),我們已經(jīng)說(shuō)完了整個(gè)初始化流程。
接下來(lái)我們挑 doCreateBean 中的三個(gè)細(xì)節(jié)出來(lái)說(shuō)說(shuō)。一個(gè)是創(chuàng)建 Bean 實(shí)例的 createBeanInstance 方法,一個(gè)是依賴注入的 populateBean 方法,還有就是回調(diào)方法 initializeBean。
注意了,接下來(lái)的這三個(gè)方法要認(rèn)真說(shuō)那也是極其復(fù)雜的,很多地方我就點(diǎn)到為止了,感興趣的讀者可以自己往里看,最好就是碰到不懂的,自己寫代碼去調(diào)試它。
創(chuàng)建 Bean 實(shí)例
我們先看看 createBeanInstance 方法。需要說(shuō)明的是,這個(gè)方法如果每個(gè)分支都分析下去,必然也是極其復(fù)雜冗長(zhǎng)的,我們挑重點(diǎn)說(shuō)。此方法的目的就是實(shí)例化我們指定的類。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 確保已經(jīng)加載了此 class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 校驗(yàn)一下這個(gè)類的訪問(wèn)權(quán)限
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
if (mbd.getFactoryMethodName() != null) {
// 采用工廠方法實(shí)例化,不熟悉這個(gè)概念的讀者請(qǐng)看附錄,注意,不是 FactoryBean
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 如果不是第一次創(chuàng)建,比如第二次創(chuàng)建 prototype bean。
// 這種情況下,我們可以從第一次創(chuàng)建知道,采用無(wú)參構(gòu)造函數(shù),還是構(gòu)造函數(shù)依賴注入 來(lái)完成實(shí)例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 構(gòu)造函數(shù)依賴注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 無(wú)參構(gòu)造函數(shù)
return instantiateBean(beanName, mbd);
}
}
// 判斷是否采用有參構(gòu)造函數(shù)
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 構(gòu)造函數(shù)依賴注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 調(diào)用無(wú)參構(gòu)造函數(shù)
return instantiateBean(beanName, mbd);
}
挑個(gè)簡(jiǎn)單的無(wú)參構(gòu)造函數(shù)構(gòu)造實(shí)例來(lái)看看:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
// 實(shí)例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
// 包裝一下,返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
我們可以看到,關(guān)鍵的地方在于:
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
這里會(huì)進(jìn)行實(shí)際的實(shí)例化過(guò)程,我們進(jìn)去看看:
// SimpleInstantiationStrategy 59
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// 如果不存在方法覆寫,那就使用 java 反射進(jìn)行實(shí)例化,否則使用 CGLIB,
// 方法覆寫 請(qǐng)參見(jiàn)附錄"方法注入"中對(duì) lookup-method 和 replaced-method 的介紹
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 利用構(gòu)造方法進(jìn)行實(shí)例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 存在方法覆寫,利用 CGLIB 來(lái)完成實(shí)例化,需要依賴于 CGLIB 生成子類,這里就不展開(kāi)了。
// tips: 因?yàn)槿绻皇褂?CGLIB 的話,存在 override 的情況 JDK 并沒(méi)有提供相應(yīng)的實(shí)例化支持
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
到這里,我們就算實(shí)例化完成了。我們開(kāi)始說(shuō)怎么進(jìn)行屬性注入。
bean 屬性注入
看完了 createBeanInstance(...) 方法,我們來(lái)看看 populateBean(...) 方法,該方法負(fù)責(zé)進(jìn)行屬性設(shè)值,處理依賴。
// AbstractAutowireCapableBeanFactory 1203
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// bean 實(shí)例的所有屬性都在這里了
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;
}
}
// 到這步的時(shí)候,bean 實(shí)例化完成(通過(guò)工廠方法或構(gòu)造方法),但是還沒(méi)開(kāi)始屬性設(shè)值,
// InstantiationAwareBeanPostProcessor 的實(shí)現(xiàn)類可以在這里對(duì) bean 進(jìn)行狀態(tài)修改,
// 我也沒(méi)找到有實(shí)際的使用,所以我們暫且忽略這塊吧
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 如果返回 false,代表不需要進(jìn)行后續(xù)的屬性設(shè)值,也不需要再經(jīng)過(guò)其他的 BeanPostProcessor 的處理
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通過(guò)名字找到所有屬性值,如果是 bean 依賴,先初始化依賴的 bean。記錄依賴關(guān)系
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通過(guò)類型裝配。復(fù)雜一些
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) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 這里有個(gè)非常有用的 BeanPostProcessor 進(jìn)到這里: AutowiredAnnotationBeanPostProcessor
// 對(duì)采用 @Autowired、@Value 注解的依賴進(jìn)行設(shè)值,這里的內(nèi)容也是非常豐富的,不過(guò)本文不會(huì)展開(kāi)說(shuō)了,感興趣的讀者請(qǐng)自行研究
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 設(shè)置 bean 實(shí)例的屬性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
initializeBean
屬性注入完成后,這一步其實(shí)就是處理各種回調(diào)了,這塊代碼比較簡(jiǎn)單。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 如果 bean 實(shí)現(xiàn)了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回調(diào)
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessBeforeInitialization 回調(diào)
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 處理 bean 中定義的 init-method,
// 或者如果 bean 實(shí)現(xiàn)了 InitializingBean 接口,調(diào)用 afterPropertiesSet() 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessAfterInitialization 回調(diào)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
大家發(fā)現(xiàn)沒(méi)有,BeanPostProcessor 的兩個(gè)回調(diào)都發(fā)生在這邊,只不過(guò)中間處理了 init-method,是不是和讀者原來(lái)的認(rèn)知有點(diǎn)不一樣了?