Spring Boot學(xué)習(xí)筆記-自動(dòng)配置原理及使用

自動(dòng)配置的使用

配置是Spring Framework的核心元素失球,必須要有東西告訴Spring如何應(yīng)用程序精堕。當(dāng)你引入Spring Boot時(shí)悍引,有個(gè)名為spring-boot-autoconfigure的JAR文件凰慈,其中包含了很多配置類(lèi)官紫。每個(gè)配置類(lèi)都在應(yīng)用程序的Classpath里引瀑,當(dāng)條件適當(dāng)時(shí)就會(huì)啟用這些配置類(lèi)狂芋。

那么什么時(shí)候算是條件適當(dāng)呢?

下面這張表格就是自動(dòng)配置中使用的條件化注解憨栽,上面限定了一些配置生效條件帜矾。這是Spring 4.0提供的條件化配置,可以判斷這個(gè)配置是該被應(yīng)用還是被忽略.

自動(dòng)配置中使用的條件化注解

舉個(gè)例子

DataSourceAutoConfiguration.png

這是Spring Boot自動(dòng)配置庫(kù)中的一個(gè)數(shù)據(jù)源配置類(lèi)。

這里添加了@ConditionOnClass({DataSource.class, EmbeddedDatabaseType.class})注解,要求Classpath里必須有DataSourceEmbeddedDatabaseType.如果它們不存在,條件就不成立,DataSourceAutoConfiguration提供的配置都會(huì)被忽略掉徒像。

當(dāng)你想要覆蓋Spring Boot的自動(dòng)配置,只需要寫(xiě)一個(gè)顯示的配置類(lèi),添加@Configuration注解,或是在xml文檔中進(jìn)行配置,Spring Boot會(huì)發(fā)現(xiàn)你的配置,使自動(dòng)配置類(lèi)不生效,以你的配置為準(zhǔn).

上表中的ConditionOnMissingBean注解是覆蓋自動(dòng)配置的關(guān)鍵.舉個(gè)覆蓋自動(dòng)配置的例子黍特。

ConditionOnMissingBean注解

這是DataSourceAutoConfiguration類(lèi)中的一個(gè)方法,ConditionOnMissingBean({DataSource.class,XADataSource.class}),要求當(dāng)前不存在DataSource.classXADataSource.class才生效.如果當(dāng)前已經(jīng)有了這兩個(gè)Bean,條件既不滿足,不會(huì)執(zhí)行PooledDataSourceConfiguration方法锯蛀。

如果上面表格的條件化注解不適用時(shí)灭衷,可以實(shí)現(xiàn)Condition接口的match()方法,然后結(jié)合Conditional注解自定義配置生效條件旁涤。

自動(dòng)配置的源碼分析

@SpringBootApplication
啟用自動(dòng)配置

從上圖可以看出SpringBoot的啟動(dòng)類(lèi)上的注解SpringBootApplecation都包含有EnableAutoConfiguration注解,意味著啟用自動(dòng)配置翔曲。

自動(dòng)導(dǎo)入配置選擇類(lèi)

跟進(jìn)EnableAutoConfiguration類(lèi)中發(fā)現(xiàn)含有@Import({AutoConfigurationImportSelector.class})注解,@Import注解也是將類(lèi)加載進(jìn)Spring容器中,這里導(dǎo)入了類(lèi)AutoConfigurationImportSelector字面意思上看是一個(gè)自動(dòng)配置導(dǎo)入的選擇器類(lèi)迫像。

selectImport方法

上圖可以看出,自動(dòng)配置大致可以分為三步瞳遍。

  1. 檢查注解是否開(kāi)啟
  2. 讀取自動(dòng)配置元數(shù)據(jù)闻妓,其實(shí)就是自動(dòng)配置類(lèi)的注解屬性
  3. 獲取符合條件的自動(dòng)配置類(lèi)

第一步,注解是否開(kāi)啟

? 這步其實(shí)就是獲取環(huán)境變量掠械,將注解類(lèi)的值進(jìn)行比較由缆。

第二步,讀取自動(dòng)配置元數(shù)據(jù)

? 跟進(jìn)方法

讀取spring-autoconfigure-metadata.properties
spring-autoconfigure-metadata.properties

META-INF/spring-autoconfigure-metadata.properties里頭放了定義了很多默認(rèn)自動(dòng)配置類(lèi)的關(guān)聯(lián)配置類(lèi)以及生效條件的指定類(lèi).

這有一個(gè)selectImports方法,通過(guò)loadMetadata()方法加載META-INF/spring-autoconfigure-metadata.properties猾蒂,存放到內(nèi)部靜態(tài)類(lèi)AutoConfigurationEntry中,這個(gè)類(lèi)存放了配置類(lèi)的類(lèi)名以及需要排除的類(lèi)名.

AutoConfigurationEntry

第三步均唉,執(zhí)行getAutoConfigurationEntry()方法,根據(jù)第二步讀取的自動(dòng)配置類(lèi)的注解屬性,開(kāi)始獲取需要生效的配置類(lèi)列表肚菠。

getAutoConfigurationEntry()
springfactories

這一步其實(shí)就是根據(jù)自帶的兩個(gè)配置文件spring-autoconfigure-metadata.properties舔箭、spring.factories加載自動(dòng)配置類(lèi)、及自動(dòng)配置類(lèi)生效的條件蚊逢,根據(jù)這些內(nèi)容去過(guò)濾一些不符合條件层扶、重復(fù)的自動(dòng)配置類(lèi),最后返回一個(gè)需要生效的自動(dòng)配置類(lèi)列表烙荷。

什么時(shí)候執(zhí)行selectImports()?

Spring boot應(yīng)用啟動(dòng)過(guò)程中使用ConfigurationClassParser分析配置類(lèi) (比如使用了@Configuration的注解類(lèi))時(shí)镜会,如果發(fā)現(xiàn)注解中存在@Import(AutoConfigurationImportSelector.class)的情況,就會(huì)創(chuàng)建一個(gè)相應(yīng)的AutoConfigurationImportSelector對(duì)象奢讨, 并調(diào)用其selectImports(AnnotationMetadata annotationMetadata對(duì)象方法public String[] selectImports(AnnotationMetadata annotationMetadata)稚叹。

這里 @EnableAutoConfiguration的導(dǎo)入@Import(EnableAutoConfigurationImportSelector.class) 就屬于這種情況【發(fā)現(xiàn)有@import注解,那么就對(duì)該導(dǎo)入類(lèi)進(jìn)行一個(gè)事例化】,所以ConfigurationClassParser會(huì)實(shí)例化一個(gè) EnableAutoConfigurationImportSelector 并調(diào)用它的 selectImports() 方法拿诸。

Spring的工具類(lèi)ConfigurationClassParser用于分析@Configuration注解的配置類(lèi)扒袖,產(chǎn)生一組ConfigurationClass對(duì)象。它的分析過(guò)程會(huì)接受一組種子配置類(lèi)(調(diào)用者已知的配置類(lèi)亩码,通常很可能只有一個(gè))季率,從這些種子配置類(lèi)開(kāi)始分析所有關(guān)聯(lián)的配置類(lèi),分析過(guò)程主要是遞歸分析配置類(lèi)的注解@Import描沟,配置類(lèi)內(nèi)部嵌套類(lèi)飒泻,找出其中所有的配置類(lèi),然后返回這組配置類(lèi)吏廉。

該工具主要由ConfigurationClassPostProcessor使用泞遗,而ConfigurationClassPostProcessor是一個(gè)BeanDefinitionRegistryPostProcessor/BeanFactoryPostProcessor,它會(huì)在容器啟動(dòng)過(guò)程中,應(yīng)用上下文上執(zhí)行各個(gè)BeanFactoryPostProcessor時(shí)被執(zhí)行席覆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末史辙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌聊倔,老刑警劉巖晦毙,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異耙蔑,居然都是意外死亡见妒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)甸陌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)须揣,“玉大人,你說(shuō)我怎么就攤上這事邀层》稻矗” “怎么了遂庄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵寥院,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我涛目,道長(zhǎng)秸谢,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任霹肝,我火速辦了婚禮估蹄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沫换。我一直安慰自己臭蚁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布讯赏。 她就那樣靜靜地躺著垮兑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漱挎。 梳的紋絲不亂的頭發(fā)上系枪,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音磕谅,去河邊找鬼私爷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛膊夹,可吹牛的內(nèi)容都是我干的衬浑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼放刨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼工秩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拓诸,失蹤者是張志新(化名)和其女友劉穎侵佃,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奠支,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馋辈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了倍谜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迈螟。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尔崔,靈堂內(nèi)的尸體忽然破棺而出答毫,到底是詐尸還是另有隱情,我是刑警寧澤季春,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布洗搂,位于F島的核電站,受9級(jí)特大地震影響载弄,放射性物質(zhì)發(fā)生泄漏耘拇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一宇攻、第九天 我趴在偏房一處隱蔽的房頂上張望惫叛。 院中可真熱鬧,春花似錦逞刷、人聲如沸嘉涌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)仑最。三九已至,卻和暖如春题篷,著一層夾襖步出監(jiān)牢的瞬間词身,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工番枚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留法严,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓葫笼,卻偏偏與公主長(zhǎng)得像深啤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子路星,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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