springboot學(xué)習(xí)二:@SpringBootApplication注解探秘

本章目的

探索springboot背后的注解料睛,逐漸解開其神秘面紗垮抗。

系統(tǒng)版本

  1. jdk1.8
  2. springboot 2.1.6.RELEASE
  3. 開發(fā)工具(IntelliJ IDEA 2018.1.5 x64)
  4. apache maven(3.6.0,本章采用maven形式管理jar包,具體配置環(huán)境變量以及使用請自行查找資料)

開始。。价说。

我們首先分析入口類Application的啟動注解@SpringBootApplication,進入源碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}

顯然 @SpringBootApplication是一個復(fù)合注解澡匪,包括以下三個注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

下面我們一起來看下

@SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

@SpringBootConfiguration繼承自@Configuration熔任,二者功能也一致,標(biāo)注當(dāng)前類是配置類唁情,
并會將當(dāng)前類內(nèi)聲明的一個或多個以@Bean注解標(biāo)記的方法的實例納入到spring容器中疑苔,并且實例名就是方法名。

@ComponentScan

@ComponentScan自動掃描并加載符合條件的組件(比如@Component和@Repository等)或者bean定義甸鸟,最終將這些bean定義加載到IoC容器中惦费。是以前的<context:component-scan>(以前使用在XML中使用的標(biāo)簽兵迅,用來掃描包配置的平行支持)。

我們可以通過basePackages等屬性來細(xì)粒度的定制@ComponentScan自動掃描的范圍薪贫,如果不指定恍箭,則默認(rèn)Spring框架實現(xiàn)會從聲明@ComponentScan所在類的package進行掃描。

這兩個注解瞧省,并不是 springboot特有的扯夭,spring時代已經(jīng)有了,對我們來說并不陌生鞍匾,今天咱們的主角是:@EnableAutoConfiguration

@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

    //是否開啟自動裝配 默認(rèn)為true交洗,可在yml文件中設(shè)置
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    //根據(jù)class來排除
    Class<?>[] exclude() default {};

        //根據(jù)class name來排除
    String[] excludeName() default {};
}

@EnableAutoConfiguration
自動配置是springboot的最大亮點,完美的展示了CoC約定由于配置橡淑。此注解构拳,正是開啟自動配置的核心。

從源碼中梁棠,可以看到注解@Import置森,@Import(AutoConfigurationImportSelector.class)

@AutoConfigurationImportSelector

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        ...
        AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
                annotationMetadata);
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
            AnnotationMetadata annotationMetadata) {
        ...
        //獲取類路徑下spring.factories下key為EnableAutoConfiguration全限定名對應(yīng)值
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        ...
    }

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    //EnableAutoConfiguration.class
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
            getBeanClassLoader());
    ...
    }

@SpringFactoriesLoader

    public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) {
        ...
        List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
        ...
    }
    public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
    }

    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
            ...
            //讀取META-INF/spring.factories文件的配置,并返回一個字符串?dāng)?shù)組
            Enumeration<URL> urls = (classLoader != null ?
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            result = new LinkedMultiValueMap<>();
            ...
    }

至此符糊,springboot自動裝配的神秘面紗已經(jīng)解開凫海。

總結(jié):@EnableAutoConfiguration作用

  • 從classpath中搜索所有META-INF/spring.factories配置文件,將其中key為org.springframework.boot.autoconfigure.EnableAutoConfiguration對應(yīng)的配置項加載到spring容器濒蒋。
  • spring.boot.enableautoconfiguration為true(默認(rèn)為true)的時候盐碱,才啟用自動配置
  • 自定義排除某些不需要的自動配置
    • 根據(jù)class來排除(exclude)
    • 根據(jù)class name來排除(excludeName)

代碼關(guān)鍵點

  1. ImportSelector(AutoConfigurationImportSelector) 該接口的方法的返回值都會被納入到spring容器管理中
  2. SpringFactoriesLoader 從classpath中搜索所有META-INF/spring.factories配置文件把兔,并讀取配置沪伙。

疑問

  • @importImportSelector县好、ImportBeanDefinitionRegistrar各有什么用围橡?
  • spring的bpp是什么?
  • Enable*的原理是什么缕贡?

下一章翁授,我們帶著這些疑問,繼續(xù)探索源碼晾咪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末收擦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谍倦,更是在濱河造成了極大的恐慌塞赂,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昼蛀,死亡現(xiàn)場離奇詭異宴猾,居然都是意外死亡圆存,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門仇哆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沦辙,“玉大人,你說我怎么就攤上這事讹剔∮脱叮” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵延欠,是天一觀的道長撞羽。 經(jīng)常有香客問我,道長衫冻,這世上最難降的妖魔是什么诀紊? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮隅俘,結(jié)果婚禮上邻奠,老公的妹妹穿的比我還像新娘。我一直安慰自己为居,他們只是感情好碌宴,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蒙畴,像睡著了一般贰镣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膳凝,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天碑隆,我揣著相機與錄音,去河邊找鬼蹬音。 笑死上煤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的著淆。 我是一名探鬼主播劫狠,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼永部!你這毒婦竟也來了独泞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤苔埋,失蹤者是張志新(化名)和其女友劉穎懦砂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡孕惜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年愧薛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衫画。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡毫炉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出削罩,到底是詐尸還是另有隱情瞄勾,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布弥激,位于F島的核電站进陡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏微服。R本人自食惡果不足惜趾疚,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望以蕴。 院中可真熱鬧糙麦,春花似錦、人聲如沸丛肮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宝与。三九已至焚廊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間习劫,已是汗流浹背咆瘟。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留榜聂,地道東北人搞疗。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓嗓蘑,卻偏偏與公主長得像须肆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桩皿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

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