Spring加載Bean流程解析

一.spring讀取配置或注解的過程

1.先通過掃描指定包路徑下的spring注解逗威,比如@Component、@Service、@Lazy @Sope等spring識(shí)別的注解或者是xml配置的屬性(通過讀取流,解析成Document嵌洼,Document)然后spring會(huì)解析這些屬性,將這些屬性封裝到BeanDefintaion這個(gè)接口的實(shí)現(xiàn)類中.

image.png

image.png

image.png

spring也會(huì)將className封恰、scope麻养、lazy等這些屬性裝配到PersonAction對(duì)應(yīng)的BeanDefintaion中.具體采用的是BeanDefinitionParser接口中的parse(Element element, ParserContext parserContext)方法,該接口有很多不同的實(shí)現(xiàn)類。通過實(shí)現(xiàn)類去解析注解或者xml然后放到BeanDefination中,BeanDefintaion的作用是集成了我們的配置對(duì)象中的各種屬性俭驮,重要的有這個(gè)bean的ClassName回溺,還有是否是Singleton春贸、對(duì)象的屬性和值等(如果是單例的話混萝,后面會(huì)將這個(gè)單例對(duì)象放入到spring的單例池中)。

image.png

二.spring的bean的生命周期

spring的bean生命周期其實(shí)最核心的分為4個(gè)步驟萍恕,只要理清三個(gè)關(guān)鍵的步驟逸嘀,其他的只是在這三個(gè)細(xì)節(jié)中添加不同的細(xì)節(jié)實(shí)現(xiàn),也就是spring的bean生命周期:

  • 實(shí)例化 Instantiation
  • 初始化
  • 使用和銷毀 Destruction
實(shí)例化和初始化的區(qū)別:實(shí)例化是在jvm的堆中創(chuàng)建了這個(gè)對(duì)象實(shí)例,此時(shí)它只是一個(gè)空的對(duì)象允粤,所有的屬性為null崭倘。而初始化的過程就是講對(duì)象依賴的一些屬性進(jìn)行賦值之后,調(diào)用某些方法來開啟一些默認(rèn)加載类垫。比如spring中配置的數(shù)據(jù)庫屬性Bean司光,在初始化的時(shí)候就會(huì)將這些屬性填充,比如driver悉患、jdbcurl等,然后初始化連接
image.png

2.1.實(shí)例化 Instantiation

AbstractAutowireCapableBeanFactory.doCreateBean中會(huì)調(diào)用createBeanInstance()方法,該階段主要是從beanDefinitionMap循環(huán)讀取bean,獲取它的屬性残家,然后利用反射(core包下有ReflectionUtil會(huì)先強(qiáng)行將構(gòu)造方法setAccessible(true))讀取對(duì)象的構(gòu)造方法(spring會(huì)自動(dòng)判斷是否是有參數(shù)還是無參數(shù),以及構(gòu)造方法中的參數(shù)是否可用),然后再去創(chuàng)建實(shí)例(newInstance)

2.2.初始化(初始化主要包括兩個(gè)步驟,一個(gè)是屬性填充售躁,另一個(gè)就是具體的初始化過程)

2.2.1.屬性賦值 PopulateBean()會(huì)對(duì)bean的依賴屬性進(jìn)行填充坞淮,@AutoWired注解注入的屬性就發(fā)生這個(gè)階段,假如我們的bean有很多依賴的對(duì)象陪捷,那么spring會(huì)依次調(diào)用這些依賴的對(duì)象進(jìn)行實(shí)例化回窘,注意這里可能會(huì)有循環(huán)依賴的問題。后面我們會(huì)講到spring是如何解決循環(huán)依賴的問題
2.2.2:初始化 Initialization
初始化的過程包括將初始化好的bean放入到spring的緩存中市袖、填充我們預(yù)設(shè)的屬性進(jìn)一步做后置處理等
3.使用和銷毀 Destruction
在Spring將所有的bean都初始化好之后啡直,我們的業(yè)務(wù)系統(tǒng)就可以調(diào)用了。而銷毀主要的操作是銷毀bean,主要是伴隨著spring容器的關(guān)閉付枫,此時(shí)會(huì)將spring的bean移除容器之中烹玉。此后spring的生命周期到這一步徹底結(jié)束,不再接受spring的管理和約束阐滩。

三.spring的BeanPostProcessor處理器

image.png
3.1.實(shí)例化階段
該階段會(huì)調(diào)用對(duì)象的空構(gòu)造方法進(jìn)行對(duì)象的實(shí)例化二打,在進(jìn)行實(shí)例化之后,會(huì)調(diào)用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法

-InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation();
這個(gè)階段允許在Bena進(jìn)行實(shí)例化之前掂榔,允許開發(fā)者自定義邏輯继效,如返回一個(gè)代理對(duì)象。不過需要注意的是假如在這個(gè)階段返回了一個(gè)不為null的實(shí)例装获,spring就會(huì)中斷后續(xù)的過程瑞信。

-BeanPostProcessor.postProcessAfterInstantiation();
這個(gè)階段是Bean實(shí)例化完畢后執(zhí)行的后處理操作,所有在初始化邏輯穴豫、裝配邏輯之前執(zhí)行

3.2.初始化階段
3.2.1.BeanPostProcessor.postProcessBeforeInitialization

該方法在bean初始化方法前被調(diào)用凡简,Spring AOP的底層處理也是通過實(shí)現(xiàn)BeanPostProcessor來執(zhí)行代理邏輯的

3.2.2.InitializingBean.afterPropertiesSet

自定義屬性值 該方法允許我們進(jìn)行對(duì)對(duì)象中的屬性進(jìn)行設(shè)置,假如在某些業(yè)務(wù)中精肃,一個(gè)對(duì)象的某些屬性為null,但是不能顯示為null秤涩,比如顯示0或者其他的固定數(shù)值,我們就可以在這個(gè)方法實(shí)現(xiàn)中將null值轉(zhuǎn)換為特定的值

3.2.3.BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)司抱。

可以在這個(gè)方法中進(jìn)行bean的實(shí)例化之后的處理筐眷,比如我們的自定義注解,對(duì)依賴對(duì)象的版本控制自動(dòng)路由切換习柠。比如有一個(gè)服務(wù)依賴了兩種版本的實(shí)現(xiàn)匀谣,我們?nèi)绾螌?shí)現(xiàn)自動(dòng)切換呢?這時(shí)候可以自定義一個(gè)路由注解,假如叫@RouteAnnotaion资溃,然后實(shí)現(xiàn)BeanPostProcessor接口武翎,在其中通過反射拿到自定義的注解@RouteAnnotaion再進(jìn)行路由規(guī)則的設(shè)定。


image.png
3.2.4.SmartInitializingSingleton.afterSingletonsInstantiated
4.1.容器啟動(dòng)運(yùn)行階段
4.1.1.SmartLifecycle.start

容器正式渲染完畢溶锭,開始啟動(dòng)階段,bean已經(jīng)在spring容器的管理下,程序可以隨時(shí)調(diào)用

5.1.容器停止銷毀
5.1.1.SmartLifecycle.stop(Runnable callback)
spring容器停止運(yùn)行
5.1.2.DisposableBean.destroy()

spring會(huì)將所有的bean銷毀,實(shí)現(xiàn)的bean實(shí)例被銷毀的時(shí)候釋放資源被調(diào)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宝恶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子暖途,更是在濱河造成了極大的恐慌卑惜,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驻售,死亡現(xiàn)場(chǎng)離奇詭異露久,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)欺栗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門毫痕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來征峦,“玉大人,你說我怎么就攤上這事消请±赴剩” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵臊泰,是天一觀的道長(zhǎng)蛉加。 經(jīng)常有香客問我,道長(zhǎng)缸逃,這世上最難降的妖魔是什么针饥? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮需频,結(jié)果婚禮上丁眼,老公的妹妹穿的比我還像新娘。我一直安慰自己昭殉,他們只是感情好苞七,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挪丢,像睡著了一般蹂风。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吃靠,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天硫眨,我揣著相機(jī)與錄音足淆,去河邊找鬼巢块。 笑死,一個(gè)胖子當(dāng)著我的面吹牛巧号,可吹牛的內(nèi)容都是我干的族奢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼丹鸿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼越走!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起靠欢,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤廊敌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后门怪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骡澈,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年掷空,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肋殴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囤锉。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖护锤,靈堂內(nèi)的尸體忽然破棺而出官地,到底是詐尸還是另有隱情,我是刑警寧澤烙懦,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布驱入,位于F島的核電站,受9級(jí)特大地震影響氯析,放射性物質(zhì)發(fā)生泄漏沧侥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一魄鸦、第九天 我趴在偏房一處隱蔽的房頂上張望宴杀。 院中可真熱鬧,春花似錦拾因、人聲如沸旺罢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扁达。三九已至,卻和暖如春蠢熄,著一層夾襖步出監(jiān)牢的瞬間跪解,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工签孔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叉讥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓饥追,卻偏偏與公主長(zhǎng)得像图仓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子但绕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容