国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實(shí)例化)

這篇具有很好參考價(jià)值的文章主要介紹了【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實(shí)例化)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

閱讀準(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é)

  1. AbstractApplicationContext#refresh:刷新方法,不用在意
  2. AbstractApplicationContext#finishBeanFactoryInitialization:在這里實(shí)例化所有剩余的(非lazy-init)單例
  3. DefaultListableBeanFactory#preInstantiateSingletons:在這里實(shí)例化所有剩余的(非lazy-init)單例(上面的方法,核心干活的方法就是這里)
  4. DefaultListableBeanFactory#getBean:獲取Bean的方法
  5. AbstractBeanFactory#doGetBean:返回指定bean的一個(gè)實(shí)例,它可以是共享的,也可以是獨(dú)立的
  6. 上面這個(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);
	}
  1. 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í)地跟著主線來研究就好,畢竟這些才是核心)

閱讀建議

  1. 看源碼,切記糾結(jié)細(xì)枝末節(jié),不然很容易陷進(jìn)去。正常來說,看主要流程就好了
  2. 遇到不懂的,多看看類注釋或者方法注釋。Spring這種優(yōu)秀源碼,注釋真的非常到位
  3. 如果你是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í)例化到底干了什么,有哪些步驟】,我們才能更好的去研究。
【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實(shí)例化),tuling學(xué)院學(xué)習(xí)筆記,spring,java,數(shù)據(jù)庫(kù)

如上圖所示,實(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ì)講到。

  1. resolveBeanClass:加載類
  2. resolveBeforeInstantiation:實(shí)例化前
  3. 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底子才懂,不了解也無所謂

  1. 優(yōu)先返回當(dāng)前線程中的ClassLoader
  2. 線程中類加載器為null的情況下,返回ClassUtils類的類加載器
  3. 如果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è)InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation()返回不為空,則直接停止遍歷。
這個(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件事情:

  1. 實(shí)例化(推斷構(gòu)造方法、實(shí)例化)
  2. BeanDefinition的后置處理
  3. 屬性注入(實(shí)例化后、屬性注入)(對(duì)的,你沒看錯(cuò),【實(shí)例化后】是在屬性注入這個(gè)方法里面被調(diào)用的)
  4. 初始化

方法解讀:正如方法注釋說的,這里【創(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),我就不截取了。這里的代碼看不看都還好,主要還是理解流程跟原則就好。

  1. 如果一個(gè)類只有一個(gè)構(gòu)造方法,不管這個(gè)構(gòu)造方法是有參還是無參,Spring都會(huì)使用這個(gè)構(gòu)造方法創(chuàng)建對(duì)象
  2. 如果有多個(gè)構(gòu)造方法,則看有沒有無參構(gòu)造方法。因?yàn)闊o參構(gòu)造方法有默認(rèn)的含義,若有,則選擇無參的構(gòu)造方法創(chuàng)建對(duì)象;
  3. 如果有多個(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)類,AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor,分別用來實(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):InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation(),比如:

@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í)到什么。

三、實(shí)例化邏輯流程圖

【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實(shí)例化),tuling學(xué)院學(xué)習(xí)筆記,spring,java,數(shù)據(jù)庫(kù)文章來源地址http://www.zghlxwxcb.cn/news/detail-648300.html

學(xué)習(xí)總結(jié)

  1. 學(xué)習(xí)了實(shí)例化的過程
  2. 學(xué)習(xí)了實(shí)例化過程中用到的2種【Bean后置處理器】:InstantiationAwareBeanPostProcessorMergedBeanDefinitionPostProcessor以及他們內(nèi)部的一些方法

到了這里,關(guān)于【Spring專題】Spring之Bean的生命周期源碼解析——階段二(IOC之實(shí)例化)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Spring】Spring之Bean生命周期源碼解析

    什么是bean的生命周期 是指bean在spring中是如何生成,如何銷毀的; spring創(chuàng)建對(duì)象的過程,就是IOC(控制反轉(zhuǎn))的過程; JFR Java Flight Record,java飛行記錄,類似于飛機(jī)的黑匣子,是JVM內(nèi)置的基于事件的JDK監(jiān)控記錄框架,主要用于問題定位和持續(xù)監(jiān)控; 入口代碼: Spring啟動(dòng)的時(shí)

    2024年02月15日
    瀏覽(23)
  • 【框架源碼】Spring源碼解析之Bean生命周期流程

    【框架源碼】Spring源碼解析之Bean生命周期流程

    觀看本文前,我們先思考一個(gè)問題,什么是Spring的bean的生命周期?這也是我們?cè)诿嬖嚨臅r(shí)候,面試官常問的一個(gè)問題。 在沒有Spring之前,我們創(chuàng)建對(duì)象的時(shí)候,采用new的方式,當(dāng)對(duì)象不在被使用的時(shí)候,由Java的垃圾回收機(jī)制回收。 而 Spring 中的對(duì)象是 bean,bean 和普通的 J

    2024年02月09日
    瀏覽(21)
  • 【深入Spring源碼解析:解密Bean的生命周期】

    Spring是Java企業(yè)級(jí)應(yīng)用開發(fā)領(lǐng)域的一顆明星,它提供了很多方便開發(fā)人員的工具和思想。在分布式系統(tǒng)中,Spring的分布式遠(yuǎn)程協(xié)作方案,比如REST、Web服務(wù)以及消息傳遞等,也是不可或缺的。 你知道嗎?在我們使用Spring時(shí),容器中存放的所有對(duì)象,在Spring啟動(dòng)的時(shí)候就完成了實(shí)

    2024年02月05日
    瀏覽(28)
  • Spring的Bean生命周期有哪些階段?

    Spring的Bean生命周期分為四個(gè)階段:實(shí)例化、屬性賦值、初始化和銷毀。 實(shí)例化:Spring容器負(fù)責(zé)創(chuàng)建Bean的實(shí)例,可以通過構(gòu)造方法或者無參構(gòu)造方法進(jìn)行實(shí)例化。 屬性賦值:Spring容器通過屬性注入的方式為Bean的屬性賦值,可以通過setter方法或者無參構(gòu)造方法進(jìn)行屬性賦值。

    2024年02月09日
    瀏覽(28)
  • 深入理解 Java Bean 的生命周期及各個(gè)階段解析

    深入理解 Java Bean 的生命周期及各個(gè)階段解析

    Java Bean是Java編程中經(jīng)常使用的重要概念,它是可重用、可移植、可序列化的組件。在Java開發(fā)中,我們常常會(huì)遇到Bean對(duì)象,但是對(duì)于Bean的生命周期和各個(gè)階段可能并不完全了解。本文將深入探討Java Bean的生命周期,逐步解析Bean對(duì)象從創(chuàng)建到銷毀的各個(gè)重要階段。 Java Bean是一

    2024年02月14日
    瀏覽(21)
  • 【Spring專題】Bean的生命周期流程圖

    【Spring專題】Bean的生命周期流程圖

    我向來不主張【通過源碼】理解業(yè)務(wù),因?yàn)槊總€(gè)人的能力有限,甚至可能會(huì)因?yàn)殚喿x錯(cuò)誤導(dǎo)致出現(xiàn)理解上的偏差,所以我決定,還是先幫大家【開天眼】,先整體看看流程圖,好知道,Spring在寫源碼的過程中到底干了啥事情。 對(duì)于【一、之前推測(cè)的簡(jiǎn)單流程圖】大家可以不看

    2024年02月13日
    瀏覽(34)
  • Spring源碼:Bean生命周期(五)

    在上一篇文章中,我們深入探討了 Spring 框架中 Bean 的實(shí)例化過程,該過程包括從 Bean 定義中加載當(dāng)前類、尋找所有實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor 接口的類并調(diào)用實(shí)例化前的方法、進(jìn)行實(shí)例化、調(diào)用 applyMergedBeanDefinitionPostProcessors 方法等多個(gè)步驟,最終生成了一個(gè)真正的

    2024年02月04日
    瀏覽(21)
  • Spring源碼:Bean生命周期(終章)

    本系列前面講解了Spring的bean定義、bean實(shí)例化、bean初始化等生命周期。這些步驟使我們能夠了解bean從創(chuàng)建到準(zhǔn)備好使用所經(jīng)歷的過程。但是,除了這些步驟,bean的銷毀也是非常重要的一步。在本系列的最后,我們將深入探討bean的銷毀過程,包括在什么情況下會(huì)發(fā)生銷毀、銷

    2024年02月06日
    瀏覽(35)
  • Spring源碼:Bean生命周期(三)

    在之前的文章中,我們已經(jīng)對(duì) bean 的準(zhǔn)備工作進(jìn)行了講解,包括 bean 定義和 FactoryBean 判斷等。在這個(gè)基礎(chǔ)上,我們可以更加深入地理解 getBean 方法的實(shí)現(xiàn)邏輯,并在后續(xù)的學(xué)習(xí)中更好地掌握 createBean 方法的實(shí)現(xiàn)細(xì)節(jié)。 講解getBean方法之前,我們先來看看他有幾種常見的用法:

    2024年02月02日
    瀏覽(23)
  • 【Spring源碼】講講Bean的生命周期

    【Spring源碼】講講Bean的生命周期

    面試官:“看過Spring源碼吧,簡(jiǎn)單說說Spring中Bean的生命周期” 大神仙:“基本生命周期會(huì)經(jīng)歷實(shí)例化 - 屬性賦值 - 初始化 - 銷毀”。 面試官:“......” 如果是普通Bean的生命周期,那么上述的回答是真正確的。確實(shí)會(huì)經(jīng)歷“實(shí)例化 - 屬性賦值 - 初始化 - 銷毀”四個(gè)階段。但

    2023年04月09日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包