SpringBoot—從 @SpringBootApplication 注解開始

0 @SpringBootApplication

標(biāo)識(shí)被注解的類是一個(gè) @Configuration 類蔬啡,在類中可以聲明一個(gè)或多個(gè) @bean 方法,并且它會(huì)觸發(fā) @EnableAutoConfiguration@ComponenetScan 的相應(yīng)功能。@SpringBootApplication 注解是一個(gè)綜合性注解盒让,等同于聲明 @Configuration刨裆、@EnableAutoConfiguration@ComponentScan 這三個(gè)注解告唆。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ...
}

@SpringBootApplication 的類聲明中沒有看到 @Configuration 注解,那是因?yàn)?@SpringBootConfiguration 其實(shí)就是一個(gè) @Configuration`` 注解簇秒。至于@EnableAutoConfiguration``` 注解的魔法功能在下面會(huì)說到鱼喉。

這篇文章不談?wù)摼唧w背后的工作原理,只是先認(rèn)識(shí)跟 @SpringBootApplication 注解相關(guān)的其他幾個(gè)注解趋观,以及帶來(lái)的作用蒲凶。先把地基打好,才能建高樓大廈拆内。

1 @Import

@Import 注解標(biāo)識(shí)可以導(dǎo)入一個(gè)或多個(gè) @Configuration 類。它提供的功能等同于以前 spring xml 配置中的 <import />標(biāo)簽宠默,可以導(dǎo)入 @Configuration 類麸恍、ImportSelector 和 ImportBeanDefinitionRegistrar 的實(shí)現(xiàn)類,以及普通的組件類搀矫。如果 XML 或其他非 @Configuration 定義的 bean 資源需要被導(dǎo)入抹沪,可以使用 @ImportResource 注解。

1.1 ImportSelector

public interface ImportSelector {
    /**
     * 基于正在導(dǎo)入的 @Configuration 的 AnnotationMetadata 來(lái)選擇應(yīng)該被導(dǎo)入的類的名字
     */
    String[] selectImports(AnnotationMetadata importingClassMetadata);
}

ImportSelector 的子類可以實(shí)現(xiàn)任何下列 org.springframework.beans.factory.Aware Aware接口瓤球,它們各自的方法都會(huì)在 selectImports()方法之前被調(diào)用融欧。

  • org.springframework.context.EnvironmentAware
  • org.springframework.beans.factory.BeanFactoryAware
  • org.springframework.beans.factory.BeanClassLoaderAware
  • org.springframework.context.ResourceLoaderAware

1.2 ImportBeanDefinitionRegistrar

public interface ImportBeanDefinitionRegistrar {
    /**
     * 基于正在導(dǎo)入的 @Configuration 的給定的注解元數(shù)據(jù)來(lái)注冊(cè) bean definition
     * bean definition 其實(shí)就是對(duì) bean 的元數(shù)據(jù)信息封裝。
     * 需要注意的是卦羡,BeanDefinitionRegistryPostProcessor 類型不會(huì)在這里注冊(cè)噪馏,因?yàn)?     * 生命周期相關(guān)的約束。
     */
    void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

}

在處理 @Configuration 時(shí)绿饵,注冊(cè)額外的 bean definition欠肾。

2 @EnableAutoConfiguration

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    Class<?>[] exclude() default {};

    String[] excludeName() default {};

}

開啟 Spring 應(yīng)用上下文的自動(dòng)配置功能,它試圖猜測(cè)你可能需要配置的 bean拟赊。

2.1 @AutoConfigurationPackage

@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}

表示包含該注解的類所在的包應(yīng)該在 AutoConfigurationPackages 中注冊(cè)刺桃。所以這個(gè)注解就能夠解釋為什么 spring boot 的啟動(dòng)類要放在 package 的最為層,以保證 spring 能夠自動(dòng)掃描到它們吸祟。

它的實(shí)現(xiàn)原理是在注解上標(biāo)注了 @Import瑟慈,導(dǎo)入了一個(gè)AutoConfigurationPackages.Registrar桃移。

2.1.1 AutoConfigurationPackages.Registrar

用于保存導(dǎo)入的配置類所在的根包。它實(shí)現(xiàn)了 ImportBeanDefinitionRegistrar 接口葛碧。注意下借杰,Registrar 類是 AutoConfigurationPackages 類的內(nèi)部類,跟上面的注解 @AutoConfigurationPackage 名字就差了一個(gè)字母吹埠,別搞混了第步。

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        register(registry, new PackageImport(metadata).getPackageName());
    }

    @Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new PackageImport(metadata));
    }
}

2.2 AutoConfigurationImportSelector

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
    // ...
}

DeferredImportSelector 用于處理自動(dòng)配置。如果需要自定義擴(kuò)展 @EnableAutoConfiguration缘琅,那么也可以擴(kuò)展此類粘都。

2.2.1 DeferredImportSelector

public interface DeferredImportSelector extends ImportSelector {
    // ...
}

DeferredImportSelector 接口是 ImportSelector 接口的一種擴(kuò)展,它是在處理完所有 @Configuration 類型的 bean 之后才會(huì)被執(zhí)行刷袍,因此翩隧,它的執(zhí)行時(shí)機(jī)是在 @Configuration 注解中的其他邏輯被處理完畢之后(包括對(duì) @ImportResource@Bean 這些注解的處理)再執(zhí)行呻纹,也就是說堆生,DeferredImportSelector 的執(zhí)行時(shí)機(jī)比 ImportSelector 更晚。

DeferredImportSelector 接口在處理有條件的選擇導(dǎo)入時(shí)非常有用雷酪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末淑仆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哥力,更是在濱河造成了極大的恐慌蔗怠,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吩跋,死亡現(xiàn)場(chǎng)離奇詭異寞射,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锌钮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門桥温,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人梁丘,你說我怎么就攤上這事侵浸。” “怎么了氛谜?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵通惫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我混蔼,道長(zhǎng)履腋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮遵湖,結(jié)果婚禮上悔政,老公的妹妹穿的比我還像新娘。我一直安慰自己延旧,他們只是感情好谋国,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迁沫,像睡著了一般芦瘾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上集畅,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天近弟,我揣著相機(jī)與錄音,去河邊找鬼挺智。 笑死祷愉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赦颇。 我是一名探鬼主播二鳄,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼媒怯!你這毒婦竟也來(lái)了订讼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扇苞,失蹤者是張志新(化名)和其女友劉穎躯嫉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杨拐,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年擂啥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哄陶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡哺壶,死狀恐怖屋吨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情山宾,我是刑警寧澤至扰,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站资锰,受9級(jí)特大地震影響敢课,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一直秆、第九天 我趴在偏房一處隱蔽的房頂上張望濒募。 院中可真熱鬧,春花似錦圾结、人聲如沸瑰剃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晌姚。三九已至,卻和暖如春歇竟,著一層夾襖步出監(jiān)牢的瞬間挥唠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工途蒋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猛遍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓号坡,卻偏偏與公主長(zhǎng)得像懊烤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宽堆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345