spring啟動(dòng)過程解析

spring啟動(dòng)分兩個(gè)階段

1、配置文件解析妈拌、注解解析階段, 生產(chǎn) BeanDefinition對象? spring配置文件中使用的占位符替換工作就是在這個(gè)階段完成的? ? (數(shù)據(jù)源的配置)

2蓬蝶、spring用之前產(chǎn)生的BeanDefinition對象完成bean的初始化和組裝工作

? 比如 事務(wù)尘分,proxy等就是在這個(gè)階段完成的

本文我只想縷清其大致過程,不關(guān)注具體實(shí)現(xiàn)細(xì)節(jié)丸氛,大致過程弄清楚了培愁,其余細(xì)節(jié)有興趣可以去翻翻詳細(xì)源碼

下面以springboot的啟動(dòng)過程為例縷縷以上兩個(gè)過程,

?我們知道啟動(dòng)springboot項(xiàng)目很簡單缓窜,初始化SpringApplication對象定续,并調(diào)用它的run方法

進(jìn)入到run方法

圖中

標(biāo)識(shí)1主要記錄容器啟動(dòng)時(shí)長,并打印日志

標(biāo)識(shí)2做了一些前置的準(zhǔn)備工作禾锤,大致了解一下就可以了

標(biāo)識(shí)3用來刷新容器私股,此處我們重點(diǎn)分析,跟進(jìn)去最終發(fā)現(xiàn)調(diào)用的是AbstractApplicationContext的refresh方法

1恩掷、this.postProcessBeanFactory(beanFactory) 跟進(jìn)去是空實(shí)現(xiàn)倡鲸,留給子類自己去實(shí)現(xiàn)

2、this.invokeBeanFactoryPostProcessors(beanFactory) 調(diào)用所有的BeanFacotryPostProcessor黄娘,其中ConfigurationClassPostProcessor值得重點(diǎn)關(guān)注峭状,后續(xù)講到

3、 this.registerBeanPostProcessors(beanFactory)注冊BeanPostProcessors到容器中

4寸宏、this.initMessageSource();初始化messageSource

5宁炫、initApplicationEventMulticaster();?初始化 事件分發(fā)器

6、onRefresh(); 通知子類刷新容器

7氮凝、registerListeners();?注冊事件監(jiān)聽器

8羔巢、finishBeanFactoryInitialization(beanFactory);初始化單例對象

9、finishRefresh();收尾工作,初始化LifecycleProcessor并調(diào)用器onRefresh方法

第一步看是怎么完成配置類的加載竿秆、解析启摄、創(chuàng)建BD對象并注冊到容器中的

我們進(jìn)入到invokeBeanFactoryPostProcessors方法里面

我們看到調(diào)用了PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法其中通過this.getBeanFactoryPostProcessors()獲取到前面準(zhǔn)備好的BeanFactoryPostProcessors列表跟進(jìn)去瞧瞧

有個(gè)很顯眼的PostProcessor對象BeanDefinitionRegistryPostProcessor調(diào)用了他的postProcessBeanDefinitionRegistry方法跟進(jìn)去發(fā)現(xiàn)調(diào)用其子類實(shí)現(xiàn)ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry

processConfigBeanDefinitions看到這個(gè)方法心里就有譜了,跟進(jìn)去代碼比較多幽钢,但是可以看到其中非常重要的一段代碼

1歉备、首先實(shí)例化ConfigurationClassParser對象并調(diào)用其parse方法用來解析 Configuration配置類并將其存放在內(nèi)部的一個(gè)Map對象configurationClasses中以備下一步使用

2、實(shí)例化ConfigurationClassBeanDefinitionReader調(diào)用其loadBeanDefinitions方法并將上一步解析得到的Map對象的keySet作為參數(shù)傳入

遍歷ConfigurationClass列表并調(diào)用loadBeanDefinitionsForConfigurationClass方法如下

不管怎么說此處就是分析ConfigurationClass并將ConfigurationClass所描述的配置類構(gòu)建成BeanDefinition對象并注冊到容器中匪燕,這里說的都是Configuration注解的類蕾羊,那我們還有很多Component,Service帽驯,Controller等注解的類呢龟再,它們是怎么加載和解析的呢?

我們再來看看ConfigurationClassParser的parser方法最后調(diào)用doProcessConfigurationClass

掃描ComponentScans定義下的所有類componentScanParser.parse()方法解析成BeanDefinitionHolder集合最后又調(diào)用processConfigurationClass方法接上前面的流程完成BeanDefintion的注冊尼变,到此完成上述過程中的第一步

再來看第二步實(shí)例化及初始化Bean并將Bean注冊到容器中的過程利凑,通過代碼的跟入發(fā)現(xiàn)都調(diào)用了AbstractBeanFactory的getBean方法,順著一直跟進(jìn)到getSingleton方法嫌术,終于在里面找到addSingleton方法將Bean的名稱和對象傳進(jìn)來哀澈,看看下面這段代碼

首先在緩存Map中獲取,如果為空則調(diào)用singletonFactory.getObject()方法創(chuàng)建一個(gè)新對象度气,最后如果是新創(chuàng)建的對象則調(diào)用addSingleton進(jìn)行注冊割按,存儲(chǔ)到本地的Map對象中,然后等我們調(diào)用context.getBean蚯嫌,其實(shí)就是在這個(gè)Map對象中獲取的

哲虾,

在創(chuàng)建新對象的時(shí)候會(huì)調(diào)用initializeBean方法我們來看看這個(gè)方法的實(shí)現(xiàn)

這里可以看到獲取所有的BeanPostProcessor,并調(diào)用postProcessBeforeInitialize()和postProcessAfterInitialization()方法對bean進(jìn)行增強(qiáng)處理丙躏。

總結(jié)

簡單的說第一階段就是加載配置類文件择示,然后調(diào)用解析器解析配置文件生成BeanDefinition對象,并調(diào)用BeanFactoryPostProcessor進(jìn)行處理之后存儲(chǔ)在Map中

然后第二階段根據(jù)BeanDefinition的定義通過反射進(jìn)行Bean的實(shí)例化晒旅,并在初始化工作中調(diào)用BeanPostProcessor進(jìn)行增強(qiáng)和組裝工作栅盲。

好了,這篇文章就到這里了废恋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谈秫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鱼鼓,更是在濱河造成了極大的恐慌拟烫,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迄本,死亡現(xiàn)場離奇詭異硕淑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門置媳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來于樟,“玉大人,你說我怎么就攤上這事拇囊∮厍” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵寥袭,是天一觀的道長路捧。 經(jīng)常有香客問我,道長传黄,這世上最難降的妖魔是什么鬓长? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮尝江,結(jié)果婚禮上涉波,老公的妹妹穿的比我還像新娘。我一直安慰自己炭序,他們只是感情好啤覆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惭聂,像睡著了一般窗声。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辜纲,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天笨觅,我揣著相機(jī)與錄音,去河邊找鬼耕腾。 笑死见剩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扫俺。 我是一名探鬼主播苍苞,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼狼纬!你這毒婦竟也來了羹呵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤疗琉,失蹤者是張志新(化名)和其女友劉穎冈欢,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盈简,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凑耻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年犯戏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拳话。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡先匪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弃衍,到底是詐尸還是另有隱情呀非,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布镜盯,位于F島的核電站岸裙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏速缆。R本人自食惡果不足惜降允,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艺糜。 院中可真熱鬧剧董,春花似錦、人聲如沸破停。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽真慢。三九已至毅臊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間黑界,已是汗流浹背管嬉。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朗鸠,地道東北人蚯撩。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像童社,于是被迫代替她去往敵國和親求厕。 傳聞我的和親對象是個(gè)殘疾皇子著隆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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