一起讀Spring源碼(一)容器的初始化

前言

對于Java開發(fā)者來說蜜唾,Spring無疑是最常用也是最基礎的框架之一杂曲。(此處省略1w字吹Spring)。相信很多同行跟我一樣袁余,只是停留在會用的階段擎勘,比如用@Component寫一個組件、用@Autowired注入其他組件等等颖榜,但是不知道為什么可以這么做棚饵,Spring是怎么實現(xiàn)的。為了了解這些掩完,我閱讀了《Spring源碼深度解析》噪漾,這本書講的很詳細,但是因為步驟多而復雜容易記混藤为,我就做了一下梳理怪与,先呈現(xiàn)大致流程,但對每個步驟進行詳細描述缅疟。

概念

概念上的東西還是要提一嘴的:

Spring用IoC容器來管理Bean分别。

BeanFactory和ApplicationContext是SpringIoC容器的兩種表現(xiàn)形式。

BeanFactory定義了簡單IoC容器的基本功能存淫。

ApplicationContext實現(xiàn)了BeanFactory耘斩,且通過繼承MessageSource、ResourceLoader桅咆、ApplicationEventPublisher接口括授,添加了許多高級容器的特性。

XmlBeanFactory

這里以XmlBeanFactory為代表岩饼,看容器是怎么工作的荚虚。

新建一個XmlBeanFactory很簡單,只需要你有一個符合格式的xml文件籍茧,里面用<bean>標簽設置你希望被容器加載的Bean:

BeanFactory bf = new XmlBeanFactory(new ClassPathResource("test.xml"))

新建了一個ClassPathResource資源對象作為參數(shù)傳入XmlBeanFactory的構(gòu)造函數(shù)版述。

點進XmlBeanFactory類,XmlBeanFactory會先調(diào)用父類構(gòu)造器寞冯,一直跟蹤到AbstractAutowireCapableBeanFactory渴析,會看到調(diào)用了三次ignoreDependencyInterface用來忽略給定接口的自動裝配功能(后面會提到);再調(diào)用this.reader.loadBeanDefinitions(Resource)吮龄,用自己持有的XmlBeanDefinitionReader解析傳入的資源俭茧。所以最宏觀的三個步驟:

1、新建了一個ClassPathResource資源漓帚。抽象出一個資源類來表示資源母债;

2、調(diào)用了ignoreDependencyInterface忽略指定接口的自動裝配功能胰默;

3场斑、委托XmlBeanDefinitionReader解析資源漓踢。

重點肯定在第三步了,點進XmlBeanDefinitionReader漏隐,到loadBeanDefinitions(EncodedResource)喧半,先從

Resource獲取InputStream構(gòu)造成InputSource,作為參數(shù)調(diào)用doLoadBeanDefinitions(InputSource, Resource)開始真正的解析青责。所以第三步下面是兩個小步驟:

3.1挺据、從Resource獲取輸入流;

3.2脖隶、調(diào)用doLoadBeanDefinitions繼續(xù)解析扁耐。

再看doLoadBeanDefinitions方法,主要是兩個方法产阱,doLoadDocument(inputSource, resource)解析輸入流返回一個Document對象婉称;registerBeanDefinitions(doc, resource)繼續(xù)解析Document返回解析的Bean數(shù)量,所以3.2下面是兩個步驟:

3.2.1构蹬、將資源解析成Document對象(這個步驟這邊就不展開了王暗,有興自究);

3.2.2庄敛、解析Document俗壹,提取注冊Bean。

來到registerBeanDefinitions方法藻烤,這里創(chuàng)建了一個BeanDefinitionDocumentReader對象負責具體解析(是不是覺得又冒出了不認識的類绷雏,框架就是這樣,遵循單一職責的原則怖亭,把一個集中的邏輯放到其他類中處理)涎显,它調(diào)用doRegisterBeanDefinitions(doc.getDocumentElement()),提取Document的root作為參數(shù)繼續(xù)解析兴猩,先查找解析profile屬性棺禾,將表示環(huán)境的屬性注冊到Environment;然后遍歷root每個子節(jié)點峭跳,如果是默認標簽,調(diào)用parseDefaultElement進行解析缺前;如果是自定義標簽蛀醉,就調(diào)用delegate.parseCustomElement。所以3.2.2下面是這幾個步驟:

3.2.2.1衅码、創(chuàng)建BeanDefinitionDocumentReader委托解析對象拯刁;

3.2.2.2、解析profile屬性到Environment逝段;

3.2.2.3垛玻、遍歷子節(jié)點割捅,繼續(xù)解析默認標簽和自定義標簽。

我們這邊主要分析默認標簽的解析帚桩,自定義的有興自究亿驾。首先根據(jù)標簽類型選擇不同的處理方法,類型分別是import账嚎、alias莫瞬、bean和beans。重點肯定是對bean標簽的解析郭蕉,進入processBeanDefinition方法疼邀,我們看到里面先委托BeanDefinitionParserDelegate解析出一個持有bean信息的BeanDefinitionHolder;如果BeanDefinitionHolder不為空且子節(jié)點下存在自定義標簽召锈,再解析它們旁振;然后對解析完成后的BeanDefinitionHolder進行注冊,注冊過程很簡單就是將BeanDefinitionHolder持有的beanName和BeanDefinition的鍵值對涨岁、beanName和每個alias別名的鍵值對保存在容器中拐袜;最后發(fā)出bean已注冊完成的事件通知,所以這里分為4步:

3.2.2.3.1卵惦、委托BeanDefinitionParserDelegate解析返回BeanDefinitionHolder阻肿;

3.2.2.3.2、解析存在的自定義標簽沮尿;

3.2.2.3.3丛塌、解析完成后注冊;

3.2.2.3.4畜疾、發(fā)出響應事件赴邻。

到了這里終于開始具體的解析,過程其實就是先解析出beanName啡捶、alias別名姥敛,然后把其余各種標簽,如class瞎暑、scope彤敛、lazy-init等屬性解析成用于屬性承載的BeanDefinition對象的成員變量,最后將beanName了赌、alias數(shù)組和BeanDefinition封裝成BeanDefinitionHolder對象返回墨榄。具體各種屬性的功能和規(guī)則這邊就不展開了,有興自究勿她。

對于import袄秩、alias和beans標簽,簡述一下:alias的解析和bean中的alias解析差不多,也是將每一個別名與beanName以map形式保存之剧;impot可以導入其他配置文件郭卫,解析過程就是找到那個文件然后遞歸進行解析;beans就是把多個bean標簽包起來背稼,然后遍歷解析每一個bean標簽贰军。

總結(jié)

畫一個流程圖作為總結(jié):


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市雇庙,隨后出現(xiàn)的幾起案子谓形,更是在濱河造成了極大的恐慌,老刑警劉巖疆前,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寒跳,死亡現(xiàn)場離奇詭異,居然都是意外死亡竹椒,警方通過查閱死者的電腦和手機童太,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胸完,“玉大人书释,你說我怎么就攤上這事∩蘅” “怎么了爆惧?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锨能。 經(jīng)常有香客問我扯再,道長,這世上最難降的妖魔是什么址遇? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任熄阻,我火速辦了婚禮,結(jié)果婚禮上倔约,老公的妹妹穿的比我還像新娘秃殉。我一直安慰自己,他們只是感情好浸剩,可當我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布钾军。 她就那樣靜靜地躺著,像睡著了一般绢要。 火紅的嫁衣襯著肌膚如雪巧颈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天袖扛,我揣著相機與錄音,去河邊找鬼。 笑死蛆封,一個胖子當著我的面吹牛唇礁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惨篱,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼盏筐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了砸讳?” 一聲冷哼從身側(cè)響起琢融,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎簿寂,沒想到半個月后漾抬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡常遂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年纳令,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片克胳。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡平绩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出漠另,到底是詐尸還是另有隱情捏雌,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布笆搓,位于F島的核電站性湿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏砚作。R本人自食惡果不足惜窘奏,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望葫录。 院中可真熱鬧着裹,春花似錦、人聲如沸米同。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽面粮。三九已至少孝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間熬苍,已是汗流浹背稍走。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工袁翁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婿脸。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓粱胜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狐树。 傳聞我的和親對象是個殘疾皇子焙压,可洞房花燭夜當晚...
    茶點故事閱讀 43,666評論 2 350

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