前言
閱讀準(zhǔn)備
由于Spring源碼分析是一個(gè)前后聯(lián)系比較強(qiáng)的過程,而且這邊分析,也是按照代碼順序講解的,所以不了解前置知識(shí)的情況下,大概率沒辦法看懂當(dāng)前的內(nèi)容。所以,特別推薦看看我前面的文章(自上而下次序):
- Spring底層核心原理解析——引導(dǎo)篇【學(xué)習(xí)難度:★★☆☆☆】
- 手寫簡(jiǎn)易Spring容器過程分析——引導(dǎo)篇【學(xué)習(xí)難度:★★☆☆☆】
- Spring之底層架構(gòu)核心概念解析【學(xué)習(xí)難度:★★★☆☆,重要程度:★★★★★】
- Bean的生命周期流程圖【學(xué)習(xí)難度:☆☆☆☆☆,重要程度:★★★★★】
- Spring之Bean的生命周期源碼解析——階段一(掃描生成BeanDefinition)【學(xué)習(xí)難度:★★☆☆☆,重要程度:★★★☆☆】
(PS:特別是《Bean的生命周期流程圖》,幫大家【開天眼】,先了解下流程。畢竟【通過業(yè)務(wù)了解代碼,遠(yuǎn)比通過代碼了解業(yè)務(wù)簡(jiǎn)單的多】?。。。。?/mark>
(PS:特別是《Bean的生命周期流程圖》,幫大家【開天眼】,先了解下流程。畢竟【通過業(yè)務(wù)了解代碼,遠(yuǎn)比通過代碼了解業(yè)務(wù)簡(jiǎn)單的多】?。。。。?/mark>
(PS:特別是《Bean的生命周期流程圖》,幫大家【開天眼】,先了解下流程。畢竟【通過業(yè)務(wù)了解代碼,遠(yuǎn)比通過代碼了解業(yè)務(wù)簡(jiǎn)單的多】?。。。。?/mark>
閱讀指引
我們?cè)谏弦还?jié)課已經(jīng)說到過了,本次Spring源碼剖析的總?cè)肟谑?code>new AnnotationConfigApplicationContext("org.tuling.spring");,這里就不再重復(fù)解釋了。本節(jié)課要說的內(nèi)容,是SpringIOC的實(shí)例化,我們這里直接給到入口吧,調(diào)用鏈如下:(調(diào)用鏈比較深,不要糾結(jié)細(xì)枝末節(jié))
- AbstractApplicationContext#refresh:刷新方法,不用在意
- AbstractApplicationContext#finishBeanFactoryInitialization:在這里實(shí)例化所有剩余的(非lazy-init)單例
- DefaultListableBeanFactory#preInstantiateSingletons:在這里實(shí)例化所有剩余的(非lazy-init)單例(上面的方法,核心干活的方法就是這里)
- DefaultListableBeanFactory#getBean:獲取Bean的方法
- AbstractBeanFactory#doGetBean:返回指定bean的一個(gè)實(shí)例,它可以是共享的,也可以是獨(dú)立的
- 上面這個(gè)
AbstractBeanFactory#doGetBean
里面的一段局部代碼寫的回調(diào)方法,如下:
// 如果是單例創(chuàng)建bean實(shí)例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
- AbstractAutowireCapableBeanFactory#createBean:這個(gè)類的中心方法:創(chuàng)建一個(gè)bean實(shí)例,填充bean實(shí)例,應(yīng)用后處理器,等等。
如上面的調(diào)用鏈所示,最后一個(gè)方法,才是我們本次要研究的核心方法。而且通過注釋,我想大家也看到了,這個(gè)方法不單單干了實(shí)例化的工作,還有屬性填充、各種后置處理器等。(PS:哈哈,同學(xué)們,我知道這個(gè)【實(shí)例化】調(diào)用鏈挺深的,但是大家不要煩惱,只要切記【不要糾結(jié)那些細(xì)枝末節(jié)】那一切都OK,我們老老實(shí)實(shí)地跟著主線來研究就好,畢竟這些才是核心)
閱讀建議
- 看源碼,切記糾結(jié)細(xì)枝末節(jié),不然很容易陷進(jìn)去。正常來說,看主要流程就好了
- 遇到不懂的,多看看類注釋或者方法注釋。Spring這種優(yōu)秀源碼,注釋真的非常到位
- 如果你是idea用戶,多用F11的書簽功能。
- Ctrl + F11 選中文件 / 文件夾,使用助記符設(shè)定 / 取消書簽 (必備)
- Shift + F11 彈出書簽顯示層 (必備)
- Ctrl +1,2,3…9 定位到對(duì)應(yīng)數(shù)值的書簽位置 (必備)
閱讀導(dǎo)航
系列上一篇文章:《【Spring專題】Spring之Bean的生命周期源碼解析——階段一(掃描生成BeanDefinition)》
系列下一篇文章:《【Spring專題】Spring之Bean的生命周期源碼解析——階段二(二)(IOC之屬性填充/依賴注入)》
課程內(nèi)容
一、SpringIOC之實(shí)例化
這里說的【實(shí)例化】,是指單例的實(shí)例化,原型prototype不包含在內(nèi)
1.1 簡(jiǎn)單回顧
大家知道,實(shí)例化的過程是怎樣的嗎?哈,我知道大部分的同學(xué)可能都不會(huì)知道。所以呢,我希望大家真的要有去看過《 Bean的聲明周期流程圖》,因?yàn)?,通過【代碼去理解業(yè)務(wù)】,遠(yuǎn)遠(yuǎn)比【通過業(yè)務(wù)理解代碼】難得多!直接看個(gè)圖吧,起碼咱得知道【實(shí)例化到底干了什么,有哪些步驟】,我們才能更好的去研究。
如上圖所示,實(shí)例化包含了:合并BeanDefinition、加載類、實(shí)例化之前、推斷構(gòu)造方法、實(shí)例化、BeanDefinition的后置處理、實(shí)例化后等,這些關(guān)鍵步驟。這就是我們本篇文章研究的核心?。?/mark>
1.2 概念回顧
在這個(gè)【實(shí)例化】過程中,涉及到了一些Spring底層設(shè)計(jì)的概念,我在上一個(gè)筆記里面有大概介紹過Spring底層概念的一些講解,不記得的同學(xué)記得回去翻一翻。
主要涉及的概念有:
- BeanDefinition(設(shè)計(jì)圖紙):BeanDefinition表示Bean定義,BeanDefinition中存在很多屬性用來描述一個(gè)Bean的特征
- BeanPostProcessor(Spring重要的拓展點(diǎn)):Bean的后置處理器,對(duì)Bean做拓展操作。我們前面說過,
BeanPostProcessor
提供了【初始化前/后】?jī)蓚€(gè)拓展方法。但是這里,Spring內(nèi)部對(duì)這個(gè)接口做了很多拓展,新增了一些繼承自BeanPostProcessor
的子類或者子接口。在實(shí)例化階段,主要用到的接口如下:-
InstantiationAwareBeanPostProcessor
,直譯過來就是:能感知實(shí)例化的Bean后置處理器。而這個(gè)繼承自BeanPostProcessor
,顯然也具備這【初始化前/后】?jī)蓚€(gè)拓展方法。另外,通過InstantiationAwareBeanPostProcessor
的名字大家也能猜到了,它肯定是具有對(duì)【實(shí)例化】階段拓展的能力的。接口定義在后面。 -
SmartInstantiationAwareBeanPostProcessor
:直譯過來就是:智能的,能感知實(shí)例化的Bean后置處理器。在這個(gè)接口中,拓展了InstantiationAwareBeanPostProcessor
接口,新增了幾個(gè)函數(shù),其中就包括了推斷構(gòu)造的實(shí)現(xiàn)。另外,這是一個(gè)框架內(nèi)部使用接口。接口定義在后面。 -
MergedBeanDefinitionPostProcessor
:直譯過來就是:合并BeanDefinition的后置處理器。運(yùn)行時(shí)用于合并bean定義的后處理器回調(diào)接口。接口定義在后面。
-
InstantiationAwareBeanPostProcessor接口定義如下:
/**
* BeanPostProcessor的子接口,用于添加實(shí)例化前回調(diào),以及實(shí)例化后但顯式屬性設(shè)置或自動(dòng)生成之前的回調(diào)。
* 通常用于抑制特定目標(biāo)bean的默認(rèn)實(shí)例化,例如創(chuàng)建具有特殊TargetSources的代理(池化目標(biāo)、惰性初始化目標(biāo)等),或者實(shí)現(xiàn)額外的注入策略,如字段注入。
* 注:此接口為專用接口,主要供框架內(nèi)部使用。建議盡可能實(shí)現(xiàn)普通的BeanPostProcessor接口。
* 自:
* 1.2
* 參見:
* org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.setCustomTargetSourceCreators, org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator
* 作者:
* 于爾根·霍勒,羅德·約翰遜
*/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 在目標(biāo)bean實(shí)例化之前應(yīng)用這個(gè)BeanPostProcessor。返回的bean對(duì)象可能是要使用的代理而不是目標(biāo)bean,從而有效地抑制目標(biāo)bean的默認(rèn)實(shí)例化。
* 如果此方法返回一個(gè)非空對(duì)象,則bean創(chuàng)建過程將會(huì)中斷。應(yīng)用的唯一進(jìn)一步處理是來自配置的BeanPostProcessors的postProcessAfterInitialization回調(diào)。
* 這個(gè)回調(diào)將應(yīng)用于帶有bean類的bean定義,以及工廠方法定義,在這種情況下,返回的bean類型將在這里傳遞。
* 后置處理器可以實(shí)現(xiàn)擴(kuò)展的SmartInstantiationAwareBeanPostProcessor接口,以便預(yù)測(cè)它們將在這里返回的bean對(duì)象的類型。
* 默認(rèn)實(shí)現(xiàn)返回null。
* 參數(shù):
* beanClass——要實(shí)例化的bean的類
* beanName—bean的名稱
* 返回:
* 要公開的bean對(duì)象,而不是目標(biāo)bean的默認(rèn)實(shí)例,或者為空,繼續(xù)進(jìn)行默認(rèn)實(shí)例化
* 拋出:
* BeansException -在錯(cuò)誤的情況下
* 參見:
* postProcessAfterInstantiation, org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClass(), org.springframework.beans.factory.support.AbstractBeanDefinition.getFactoryMethodName()
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 在bean通過構(gòu)造函數(shù)或工廠方法實(shí)例化之后,但在Spring屬性填充(來自顯式屬性或自動(dòng)裝配)發(fā)生之前執(zhí)行操作。
* 這是在Spring自動(dòng)裝配開始之前對(duì)給定bean實(shí)例執(zhí)行自定義字段注入的理想回調(diào)。
* 默認(rèn)實(shí)現(xiàn)返回true。
* 參數(shù):
* Bean—已創(chuàng)建的Bean實(shí)例,其屬性尚未設(shè)置
* beanName—bean的名稱
* 返回:
* 如果應(yīng)該在bean上設(shè)置屬性,則為True;如果應(yīng)該跳過屬性人口,則為False。正常的實(shí)現(xiàn)應(yīng)該返回true。返回false還將阻止在此bean實(shí)例上調(diào)用任何后續(xù)的InstantiationAwareBeanPostProcessor實(shí)例。
* 拋出:
* BeansException -在錯(cuò)誤的情況下
* 參見:
* postProcessBeforeInstantiation
*/
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**
* 在工廠將給定的屬性值應(yīng)用到給定的bean之前,對(duì)它們進(jìn)行后處理,不需要任何屬性描述符。
* 如果實(shí)現(xiàn)提供自定義postProcessPropertyValues實(shí)現(xiàn),則應(yīng)該返回null(默認(rèn)值),否則則返回pvs。在該接口的未來版本中(刪除了postProcessPropertyValues),默認(rèn)實(shí)現(xiàn)將直接返回給定的pv。
* 參數(shù):
* PVS—工廠將要應(yīng)用的屬性值(永遠(yuǎn)不會(huì)為空)
* bean——已創(chuàng)建的bean實(shí)例,但其屬性尚未設(shè)置
* beanName—bean的名稱
* 返回:
* 應(yīng)用于給定bean的實(shí)際屬性值(可以是傳入的PropertyValues實(shí)例),或者null,它繼續(xù)處理現(xiàn)有屬性,但特別地繼續(xù)調(diào)用postProcessPropertyValues(需要為當(dāng)前bean類初始化PropertyDescriptors)。
* 拋出:
* BeansException -在錯(cuò)誤的情況下
* 自:
* 5.1
* 參見:
* postProcessPropertyValues
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
* 在工廠將給定屬性值應(yīng)用到給定bean之前,對(duì)它們進(jìn)行后處理。允許檢查是否滿足所有依賴項(xiàng),例如基于bean屬性設(shè)置器上的“Required”注釋。
* 還允許替換要應(yīng)用的屬性值,通常通過基于原始PropertyValues創(chuàng)建新的MutablePropertyValues實(shí)例,添加或刪除特定值。
* 默認(rèn)實(shí)現(xiàn)按原樣返回給定的pv。
* 棄用
* 從5.1開始,支持postProcessProperties(PropertyValues, Object, String)
* 參數(shù):
* PVS—工廠將要應(yīng)用的屬性值(永遠(yuǎn)不會(huì)為空)
* PDS——目標(biāo)bean的相關(guān)屬性描述符(忽略了依賴類型——工廠專門處理的依賴類型——已經(jīng)過濾掉了)
* bean——已創(chuàng)建的bean實(shí)例,但其屬性尚未設(shè)置
* beanName—bean的名稱
* 返回:
* 應(yīng)用于給定bean的實(shí)際屬性值(可以是傳入的PropertyValues實(shí)例),或者為null以跳過屬性填充
* 拋出:
* BeansException -在錯(cuò)誤的情況下
* 參見:
* postProcessProperties, org.springframework.beans.MutablePropertyValues
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
SmartInstantiationAwareBeanPostProcessor接口定義如下:
/**
* 擴(kuò)展了InstantiationAwareBeanPostProcessor接口,添加了一個(gè)回調(diào)函數(shù),用于預(yù)測(cè)被處理bean的最終類型。
* 注:此接口為專用接口,主要供框架內(nèi)部使用。一般來說,應(yīng)用程序提供的后處理器應(yīng)該簡(jiǎn)單地實(shí)現(xiàn)普通的BeanPostProcessor接口,或者從InstantiationAwareBeanPostProcessorAdapter類派生。即使在點(diǎn)發(fā)布版本中,也可能向該接口添加新方法。
* 自:
* 2.0.3
* 參見:
* InstantiationAwareBeanPostProcessorAdapter
* 作者:
* Juergen hoel
*/
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* 預(yù)測(cè)這個(gè)處理器的postProcessBeforeInstantiation回調(diào)最終返回的bean的類型。
* 默認(rèn)實(shí)現(xiàn)返回null。
* 參數(shù):
* beanClass—bean的原始類beanName—bean的名稱
* 返回:
* bean的類型,如果不可預(yù)測(cè),則為空
* 拋出:
* BeansException -在錯(cuò)誤的情況下
*/
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 確定要為給定bean使用的候選構(gòu)造函數(shù)。
* 默認(rèn)實(shí)現(xiàn)返回null。
* 參數(shù):
* beanClass—bean的原始類(不為空)beanName—bean的名稱
* 返回:
* 候選構(gòu)造函數(shù),如果未指定,則為空
* 拋出:
* BeansException -在錯(cuò)誤的情況下
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* 獲取對(duì)指定bean的早期訪問的引用,通常是為了解析循環(huán)引用。
* 這個(gè)回調(diào)讓后處理器有機(jī)會(huì)盡早公開包裝器——也就是說,在目標(biāo)bean實(shí)例完全初始化之前。暴露的對(duì)象應(yīng)該等同于postProcessBeforeInitialization / postProcessAfterInitialization所暴露的對(duì)象。請(qǐng)注意,此方法返回的對(duì)象將用作bean引用,除非后處理器返回與所述后處理回調(diào)不同的包裝器。換句話說:那些處理后回調(diào)可能最終公開相同的引用,或者返回那些后續(xù)回調(diào)的原始bean實(shí)例(如果受影響的bean的包裝器已經(jīng)為對(duì)該方法的調(diào)用構(gòu)建了,那么默認(rèn)情況下它將作為最終bean引用公開)。
* 默認(rèn)實(shí)現(xiàn)按原樣返回給定的bean。
* 參數(shù):
* bean—原始bean實(shí)例beanName—bean的名稱
* 返回:
* 要作為bean引用公開的對(duì)象(通常將傳入的bean實(shí)例作為默認(rèn)值)
* 拋出:
* BeansException -在錯(cuò)誤的情況下
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
MergedBeanDefinitionPostProcessor接口定義如下:
/**
* 運(yùn)行時(shí)用于合并bean定義的后處理器回調(diào)接口。BeanPostProcessor實(shí)現(xiàn)可以實(shí)現(xiàn)這個(gè)子接口,以便對(duì)合并的bean定義(原始bean定義的處理副本)進(jìn)行后處理,Spring BeanFactory使用合并的bean定義來創(chuàng)建bean實(shí)例。
* 例如,postProcessMergedBeanDefinition方法可以對(duì)bean定義進(jìn)行內(nèi)省,以便在對(duì)bean的實(shí)際實(shí)例進(jìn)行后處理之前準(zhǔn)備一些緩存的元數(shù)據(jù)。也允許修改bean定義,但只允許修改用于并發(fā)修改的定義屬性。本質(zhì)上,這只適用于在RootBeanDefinition本身上定義的操作,而不適用于其基類的屬性。
* 自:
* 2.5
* 參見:
* org.springframework.beans.factory.config.ConfigurableBeanFactory.getMergedBeanDefinition
* 作者:
* Juergen hoel
*/
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
* 對(duì)指定bean的給定合并bean定義進(jìn)行后處理。
* 參數(shù):
* beanDefinition—為bean合并的bean定義beanType—托管bean實(shí)例的實(shí)際類型beanName—bean的名稱
* 參見:
* AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* 通知指定名稱的bean定義已被重置,并且此后處理器應(yīng)清除受影響bean的所有元數(shù)據(jù)。
* 默認(rèn)實(shí)現(xiàn)為空。
* 參數(shù):
* beanName—bean的名稱
* 自:
* 5.1
* 參見:
* DefaultListableBeanFactory.resetBeanDefinition
*/
default void resetBeanDefinition(String beanName) {
}
}
這里還是有一點(diǎn)想要提醒各位的,BeanPostProcessor
是被Spring定義為【鉤子】的,而鉤子,很多時(shí)候都是為了改變系統(tǒng)原有行為的。這種改變,通常體現(xiàn)在:對(duì)Bean生命周期的影響,或者某個(gè)生命周期完成對(duì)象的改變等等。(這么說有點(diǎn)晦澀難懂,通俗點(diǎn)講就是:Bean可能不會(huì)經(jīng)過完整生命周期,比如【實(shí)例化前】之后,直接就跳到【初始化后】了,沒有經(jīng)過原本定義的【實(shí)例化】、【實(shí)例化后】、【其他后置處理】等;或者,原本初始化動(dòng)作是Spring幫我門完成的,但是由于我們自己介入了,Spring就不幫我們初始化了,而是按照程序員意愿)
文章鏈接:
《【Spring專題】Spring之底層架構(gòu)核心概念解析》
1.3 核心方法講解
整個(gè)IOC實(shí)例化的主干過程,主要涉及了【2個(gè)類,11個(gè)核心方法】。下面,我們將會(huì)按照調(diào)用次序,依次講解各個(gè)方法。
二、方法講解
我們?cè)谏厦嬲f到過,這里的實(shí)例化過程包含了:合并BeanDefinition、加載類、實(shí)例化之前、推斷構(gòu)造方法、實(shí)例化、BeanDefinition的后置處理、實(shí)例化后等關(guān)鍵步驟。所以,在整個(gè)調(diào)用鏈上,基本上就是干了這些事情。
我們前面說過,本次的實(shí)例化代碼入口如下:
// 如果是單例創(chuàng)建bean實(shí)例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
2.1 AbstractBeanFactory#getMergedLocalBeanDefinition:合并BeanDefinition
方法調(diào)用鏈:AbstractBeanFactory#doGetBean里面調(diào)用的
全路徑:org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
方法注釋:返回合并的RootBeanDefinition,如果指定的bean對(duì)應(yīng)于子bean定義,則遍歷父bean定義。
我們?cè)谏瞎?jié)課最后的地方提到過這個(gè),這邊就不重復(fù)講了,但是,他是算在實(shí)例化過程里面的,嘻嘻
2.2 AbstractAutowireCapableBeanFactory#createBean:創(chuàng)建Bean
方法調(diào)用鏈:AbstractBeanFactory#doGetBean里面調(diào)用的
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
方法注釋:這個(gè)類的中心方法:創(chuàng)建一個(gè)bean實(shí)例,填充bean實(shí)例,應(yīng)用后處理器,等等。
源碼如下:
@Override
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<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 不用管這個(gè)
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 步驟二:實(shí)例化前
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);
}
try {
// 步驟三:創(chuàng)建Bean
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);
}
}
方法解讀:上面代碼老長(zhǎng)一段,trt-catch
占了一半,啊哈哈。 這里面的步驟就三個(gè),下面也會(huì)講到。
- resolveBeanClass:加載類
- resolveBeforeInstantiation:實(shí)例化前
- doCreateBean:真正創(chuàng)建Bean的地方
2.3 AbstractAutowireCapableBeanFactory#resolveBeanClass:加載類
PS:不算很重要,知道有這個(gè)步驟就好
方法調(diào)用鏈:由2.2的createBean調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeanClass
方法注釋:這個(gè)類的中心方法:創(chuàng)建一個(gè)bean實(shí)例,填充bean實(shí)例,應(yīng)用后處理器,等等。
源碼如下:
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
方法解讀:這個(gè)代碼外層挺簡(jiǎn)單的,也許大家對(duì)比System.getSecurityManager() != null
這個(gè)比較難理解而已。這是Spring內(nèi)部的一個(gè)安全管理器,很多時(shí)候都是不開啟的。后面也會(huì)出現(xiàn)大量這種代碼,反正遇到這個(gè)就直接看else
的邏輯就好了。至于里層的doResolveBeanClass
源碼如下:
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
// 步驟一:獲取默認(rèn)的類加載器
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
// 步驟二:在我們這個(gè)調(diào)用鏈上不會(huì)走這里,因?yàn)閠ypesToMatch為null
if (!ObjectUtils.isEmpty(typesToMatch)) {
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
// 步驟三
String className = mbd.getBeanClassName();
if (className != null) {
// 步驟3.1:這里也不用怎么看,這是Spring表達(dá)式解析的東西。Spring表達(dá)式這個(gè)東西我們用的很少(類似EL表達(dá)式,這樣來理解)
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
if (dynamicLoader != null) {
try {
// 步驟3.2 加載類
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// 步驟四:正常來說走的是這里。使用默認(rèn)的類加載器加載類
return mbd.resolveBeanClass(beanClassLoader);
}
方法解讀:在這里,大體分為4個(gè)步驟。步驟一就是獲取類加載器,往里追蹤會(huì)發(fā)現(xiàn),實(shí)際上調(diào)用的是ClassUtils.getDefaultClassLoader()
方法。里面的代碼挺簡(jiǎn)單的,獲取原則如下:(需要一點(diǎn)JVM底子才懂,不了解也無所謂)
- 優(yōu)先返回當(dāng)前線程中的ClassLoader
- 線程中類加載器為null的情況下,返回ClassUtils類的類加載器
- 如果ClassUtils類的類加載器為空,那么則表示是Bootstrap類加載器加載的ClassUtils類,那么則返回系統(tǒng)類加載器
步驟二,就是第一個(gè)if
,在我們這里的調(diào)用鏈上是不會(huì)進(jìn)來這里的,因?yàn)?code>typeToMatch是null;
步驟三,可看可不看,一般也不會(huì)進(jìn)來這里。這是Spring表達(dá)式解析的東西。Spring表達(dá)式這個(gè)東西我估計(jì)大部分人都沒用過吧…(類似EL表達(dá)式,這樣來理解)
步驟四,正常來說會(huì)執(zhí)行到這里,然后在這里進(jìn)行類加載,并且通過反射獲得class對(duì)象,代碼如下所示:
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName();
if (className == null) {
return null;
}
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}
*2.4 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation:【實(shí)例化前】入口
(PS:終于來到這里了,這才是核心考點(diǎn))
方法調(diào)用鏈:由2.2的createBean調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
方法注釋:應(yīng)用實(shí)例化前的后處理器,解析指定bean是否存在實(shí)例化前的快捷方式。
源碼如下:
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;
}
方法解讀:代碼短短的幾行。首先通過hasInstantiationAwareBeanPostProcessors
看看是否有InstantiationAwareBeanPostProcessors
。有,則調(diào)用對(duì)應(yīng)的【實(shí)例化前】方法,即applyBeanPostProcessorsBeforeInstantiation
(這里才是真正干活的地方,后面介紹)。
這里有一個(gè)細(xì)節(jié),那就是applyBeanPostProcessorsBeforeInstantiation
如果返回的對(duì)象不為空,則直接調(diào)用applyBeanPostProcessorsAfterInitialization
走bean的【初始化后】方法了。這說明Bean的生命周期被改變?。《?,如果這里的Bean有值的話,外層直接返回創(chuàng)建成功了,不會(huì)繼續(xù)往下走了,如下所示:(2.2的createBean調(diào)用處代碼)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
2.5 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation:【實(shí)例化前】真正干活的地方
方法調(diào)用鏈:由2.4的resolveBeforeInstantiation調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
方法注釋:將InstantiationAwareBeanPostProcessors應(yīng)用到指定的bean定義(通過類和名稱),調(diào)用它們的postProcessBeforeInstantiation方法。如果返回不為空,則無需Spring幫我們實(shí)例化了
源碼如下:
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
方法解讀:這里終于出現(xiàn)我們之前說的核心InstantiationAwareBeanPostProcessor
了。老樣子,遍歷所有的InstantiationAwareBeanPostProcessor
,然后調(diào)用postProcessBeforeInstantiation()
。這里只要找到一個(gè)InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation()
返回不為空,則直接停止遍歷。
這個(gè)方法其實(shí)隱含的意思是:在Spring幫我們實(shí)例化之前,Spring會(huì)先去找找看,用戶有沒有對(duì)當(dāng)前beanName對(duì)應(yīng)的class有自己的實(shí)例化想法,如果有,則Spring就不幫我們創(chuàng)建了。
2.6 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization:第一次可能調(diào)用【初始化后】
方法調(diào)用鏈:由2.4的resolveBeforeInstantiation調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
方法注釋:應(yīng)用初始化后方法。通常調(diào)用此方法的時(shí)候,會(huì)認(rèn)為已經(jīng)經(jīng)過了屬性填充、初始化等
源碼如下:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
方法解讀:看,這里直接獲取所有BeanPostProcessor
接口,然后應(yīng)用postProcessAfterInitialization()
方法。這里有個(gè)空判斷,是接口要求這么做的。返回null表示不想繼續(xù)執(zhí)行剩余的BeanPostProcessor
接口
2.7 AbstractAutowireCapableBeanFactory#doCreateBean:【實(shí)例化】入口(包括后續(xù)的實(shí)例化過程)
方法調(diào)用鏈:由2.2的createBean調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
方法注釋:AbstractAutowireCapableBeanFactory這個(gè)類的中心方法:創(chuàng)建一個(gè)bean實(shí)例,填充bean實(shí)例,應(yīng)用后處理器,等等
源碼很長(zhǎng),就不截取了。在這里個(gè)方法里面,主要干了4件事情:
- 實(shí)例化(推斷構(gòu)造方法、實(shí)例化)
- BeanDefinition的后置處理
- 屬性注入(實(shí)例化后、屬性注入)(對(duì)的,你沒看錯(cuò),【實(shí)例化后】是在屬性注入這個(gè)方法里面被調(diào)用的)
- 初始化
方法解讀:正如方法注釋說的,這里【創(chuàng)建一個(gè)bean實(shí)例,填充bean實(shí)例,應(yīng)用后處理器】等等。這意味著,在這里包含了【實(shí)例化】過程中剩余的==【推斷構(gòu)造方法、實(shí)例化、BeanDefinition的后置處理、實(shí)例化后等】==步驟。另外,下一個(gè)章節(jié)會(huì)說的【IOC屬性填充】、【IOC-Aware回調(diào)】、【IOC初始化】等階段入口其實(shí)也是在這個(gè)方法中。
*2.8 AbstractAutowireCapableBeanFactory#createBeanInstance:實(shí)例化
方法調(diào)用鏈:由2.7的doCreateBean調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
方法注釋:AbstractAutowireCapableBeanFactory這個(gè)類的中心方法:創(chuàng)建一個(gè)bean實(shí)例,填充bean實(shí)例,應(yīng)用后處理器,等等
源碼如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 步驟一:再次確保類已經(jīng)被加載
Class<?> beanClass = resolveBeanClass(mbd, beanName);
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());
}
// 步驟二:使用Supplier創(chuàng)建對(duì)象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 步驟三:工廠方法創(chuàng)建對(duì)象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
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) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// 步驟四:推斷構(gòu)造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 步驟五:實(shí)例化
return instantiateBean(beanName, mbd);
}
方法解讀:這里在實(shí)例化Bean的時(shí)候,采用了多種方式。如:
2.8.1 Supplier創(chuàng)建對(duì)象
Supplier,直譯:供應(yīng)商。
首先判斷BeanDefinition中是否設(shè)置了Supplier,如果設(shè)置了則調(diào)用Supplier的get()得到對(duì)象。得直接使用BeanDefinition對(duì)象來設(shè)置Supplier,比如:
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setInstanceSupplier(new Supplier<Object>() {
@Override
public Object get() {
return new UserService();
}
});
context.registerBeanDefinition("userService", beanDefinition);
2.8.2 工廠方法創(chuàng)建對(duì)象
如果沒有設(shè)置Supplier,則檢查BeanDefinition中是否設(shè)置了factoryMethod,也就是工廠方法,有兩種方式可以設(shè)置factoryMethod,比如:
方式一:
<bean id="userService" class="com.zhouyu.service.UserService" factory-method="createUserService" />
對(duì)應(yīng)的UserService類為:
public class UserService {
public static UserService createUserService() {
System.out.println("執(zhí)行createUserService()");
UserService userService = new UserService();
return userService;
}
public void test() {
System.out.println("test");
}
}
方式二:
<bean id="commonService" class="com.zhouyu.service.CommonService"/>
<bean id="userService1" factory-bean="commonService" factory-method="createUserService" />
對(duì)應(yīng)的CommonService的類為:
public class CommonService {
public UserService createUserService() {
return new UserService();
}
}
Spring發(fā)現(xiàn)當(dāng)前BeanDefinition方法設(shè)置了工廠方法后,就會(huì)區(qū)分這兩種方式,然后調(diào)用工廠方法得到對(duì)象。
值得注意的是,我們通過@Bean所定義的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常類似,@Bean所注解的方法就是factoryMethod,AppConfig對(duì)象就是factoryBean。如果@Bean所所注解的方法是static的,那么對(duì)應(yīng)的就是方式一。
2.8.3 構(gòu)造方法創(chuàng)建對(duì)象
RT。
2.9 AbstractAutowireCapableBeanFactory#autowireConstructor:推斷構(gòu)造方法
方法調(diào)用鏈:由2.7的createBeanInstance調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireConstructor
方法注釋:推斷構(gòu)造方法,并且創(chuàng)建對(duì)象。
代碼好長(zhǎng),我就不截取了。這里的代碼看不看都還好,主要還是理解流程跟原則就好。
- 如果一個(gè)類只有一個(gè)構(gòu)造方法,不管這個(gè)構(gòu)造方法是有參還是無參,Spring都會(huì)使用這個(gè)構(gòu)造方法創(chuàng)建對(duì)象
- 如果有多個(gè)構(gòu)造方法,則看有沒有無參構(gòu)造方法。因?yàn)闊o參構(gòu)造方法有默認(rèn)的含義,若有,則選擇無參的構(gòu)造方法創(chuàng)建對(duì)象;
- 如果有多個(gè)構(gòu)造方法,且沒有無參,則看構(gòu)造方法上是否有@Autowired注解,有就選擇,沒有就報(bào)錯(cuò)
額外的,在推斷構(gòu)造方法邏輯中除開會(huì)去選擇構(gòu)造方法以及查找入?yún)?duì)象意外,會(huì)還判斷是否在對(duì)應(yīng)的類中是否存在使用**@Lookup注解**了方法。如果存在則把該方法封裝為L(zhǎng)ookupOverride對(duì)象并添加到BeanDefinition中。
?
在實(shí)例化時(shí),如果判斷出來當(dāng)前BeanDefinition中沒有LookupOverride,那就直接用構(gòu)造方法反射得到一個(gè)實(shí)例對(duì)象。如果存在LookupOverride對(duì)象,也就是類中存在@Lookup注解了的方法,那就會(huì)生成一個(gè)代理對(duì)象。
@Lookup注解就是方法注入,使用demo如下:
@Component
public class UserService {
private OrderService orderService;
public void test() {
OrderService orderService = createOrderService();
System.out.println(orderService);
}
@Lookup("orderService")
public OrderService createOrderService() {
return null;
}
}
2.10 AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors:BeanDefinition后置處理
方法調(diào)用鏈:由2.7的doCreateBean調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
方法注釋:將MergedBeanDefinitionPostProcessors應(yīng)用于指定的bean定義,調(diào)用它們的postProcessMergedBeanDefinition方法。
源碼如下:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
方法解讀:Bean對(duì)象實(shí)例化出來之后,接下來就應(yīng)該給對(duì)象的屬性賦值了。在真正給屬性賦值之前,Spring又提供了一個(gè)擴(kuò)展點(diǎn),即當(dāng)前的MergedBeanDefinitionPostProcessors
。這里的主要難點(diǎn)還是,這種類型的BeanPostProcessor
的應(yīng)用場(chǎng)景,可能才是大家比較關(guān)心的。那你們覺得,這里的主要應(yīng)用場(chǎng)景應(yīng)該是什么呢?其實(shí),按照Spring的生命周期來說,他現(xiàn)在提供給你的拓展點(diǎn),只能是【實(shí)例化】階段后的生命周期了,畢竟過去已經(jīng)發(fā)生的已經(jīng)沒辦法改變。所以,我們可以在這里,干預(yù)【初始化】這個(gè)階段,如下示例:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Object newUser = context.getBean("user");
System.out.println(newUser);
}
// 聲明bean
@Component
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void myInit() {
System.out.println("這是我自己指定的初始化方法");
}
}
// 聲明一個(gè)MergedBeanDefinitionPostProcessor,然后改變了User這個(gè)Bean的初始化方法
@Component
public class MyBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanName.equals("user")) {
beanDefinition.setInitMethodName("myInit");
}
}
}
PS:在Spring源碼中,這個(gè)后置處理器有一個(gè)非常重要的使用場(chǎng)景,那就是SpringIOC【依賴注入】中的【尋找注入點(diǎn)】。這里會(huì)用到兩個(gè)該后置處理器的實(shí)現(xiàn)類,AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
,分別用來實(shí)現(xiàn)@Autowired和@Resource【尋找注入點(diǎn)】的邏輯,并緩存在對(duì)象的一個(gè)Map中(injectionMetadataCache),為依賴注入做準(zhǔn)備。
2.11 AbstractAutowireCapableBeanFactory#populateBean:屬性注入(包含:實(shí)例化后)
(PS:屬性注入不是我們這里需要關(guān)注的地方,但因?yàn)椤緦?shí)例化后】在這個(gè)方法里面,所以就只能點(diǎn)進(jìn)來了)
方法調(diào)用鏈:由2.7的doCreateBean調(diào)用過來
全路徑:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
方法注釋:使用來自bean定義的屬性值在給定的BeanWrapper中填充bean實(shí)例(屬性填充/依賴注入)。
populateBean中關(guān)鍵源碼如下:
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
方法解讀:在處理完BeanDefinition后,Spring又設(shè)計(jì)了一個(gè)擴(kuò)展點(diǎn):InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation()
,比如:
@Component
public class ZhouyuInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
UserService userService = (UserService) bean;
userService.test();
}
return true;
}
}
上述代碼就是對(duì)userService所實(shí)例化出來的對(duì)象進(jìn)行處理。這個(gè)擴(kuò)展點(diǎn),在Spring源碼中基本沒有怎么使用。估計(jì)是為了后面拓展做準(zhǔn)備
方法總結(jié)后
以后可能不這么寫了,挺麻煩的。我這樣圈關(guān)鍵方法跟鏈路的原因,純粹是想加深自己的印象,我也不知道放出來給大伙看,你們能否學(xué)習(xí)到什么。文章來源:http://www.zghlxwxcb.cn/news/detail-648300.html
三、實(shí)例化邏輯流程圖
文章來源地址http://www.zghlxwxcb.cn/news/detail-648300.html
學(xué)習(xí)總結(jié)
- 學(xué)習(xí)了實(shí)例化的過程
- 學(xué)習(xí)了實(shí)例化過程中用到的2種【Bean后置處理器】:
InstantiationAwareBeanPostProcessor
和MergedBeanDefinitionPostProcessor
以及他們內(nèi)部的一些方法
到了這里,關(guān)于【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實(shí)例化)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!