概 述
SpringBoot 約定大於配置 的功力讓我們如沐春風,在我之前寫的文章《從SpringBoot到SpringMVC》
也對比過 SpringBoot 和 SpringMVC 這兩個框架,不過最終 SpringBoot 以超高的程式碼訊雜比 和 易上手性 讓我們映像頗深。
但歸根結底,不論 SpringBoot 或者 SpringMVC 應用本質上依然是一個基於 Spring的應用,只不過在後者臉龐上蒙上了一層神祕的面紗而已!
回到 SpringBoot 的話題,我們在開發基於 SpringBoot 的應用時,用到了一些新的註解和類,正式由於其存在,才讓JavaEE的開發如魚得水。這其中我們用的最多的註解之一,當屬 SpringBoot 應用啟動類上的 @SpringBootApplication 註解了
本文就來看看它到底是個啥!
注: 本文首發於 My 公眾號 CodeSheep ,可 長按 或 掃描 下面的 小心心 來訂閱 ↓ ↓ ↓
@SpringBootApplication 背後到底是什麼?
@SpringBootApplication註解實際上是SpringBoot提供的一個複合註解,我們來看一看其原始碼:
@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 {
...
}
看得很清楚,其是一個合成體,但其中最重要的三個註解分別是:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
我們不妨稱其為 “ 三體結構 ” 吧!
如果我們不怕麻煩,在 SpringBoot 應用的啟動類上用這個三個註解代替@SpringBootApplication 註解發現也是沒問題的:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class TestSpringBootApplication {
...
}
下面分別剖析一下這三個註解的功效!
@SpringBootConfiguration
看程式碼吧,程式碼裡是這樣寫的:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
這說明 @SpringBootConfiguration 也是來源於 @Configuration,二者功能都是將當前類標註為配置類,並將當前類裡以 @Bean 註解標記的方法的例項注入到srping容器中,例項名即為方法名。
至於@Configuration,我想在非SpringBoot時代大家應該不陌生吧,作用是配置Spring容器,也即 JavaConfig 形式的 Spring IoC 容器的配置類所使用。
到目前來看,好像還沒有什麼新東西!!!
@EnableAutoConfiguration
再繼續看程式碼,程式碼是這樣的:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
@EnableAutoConfiguration 註解啟用自動配置,其可以幫助 SpringBoot 應用將所有符合條件的 @Configuration 配置都載入到當前 IoC 容器之中,可以簡要用圖形示意如下:
接下來我們對照原始碼,來解釋一下這個流程:
- @EnableAutoConfiguration 藉助 AutoConfigurationImportSelector 的幫助,而後者通過實現 selectImports() 方法來匯出 Configuration
- AutoConfigurationImportSelector 類的 selectImports() 方法裡面通過呼叫Spring Core 包裡 SpringFactoriesLoader 類的 loadFactoryNames()方法
- 最終通過 SpringFactoriesLoader.loadFactoryNames() 讀取了 ClassPath 下面的 META-INF/spring.factories 檔案來獲取所有匯出類。
而spring.factories 檔案裡關於 EnableAutoConfiguration 的配置其實就是一個鍵值對結構,樣子大概長下面這樣:
說了這麼多,如果從稍微巨集觀一點的角度 概括總結 上述這一過程那就是:
從 ClassPath下掃描所有的 META-INF/spring.factories 配置檔案,並將spring.factories 檔案中的 EnableAutoConfiguration 對應的配置項通過反射機制例項化為對應標註了 @Configuration 的形式的IoC容器配置類,然後注入IoC容器。
@ComponentScan
@ComponentScan 對應於XML配置形式中的 <context:component-scan>,用於將一些標註了特定註解的bean定義批量採集註冊到Spring的IoC容器之中,這些特定的註解大致包括:
- @Controller
- @Entity
- @Component
- @Service
- @Repository
等等
對於該註解,還可以通過 basePackages 屬性來更細粒度的控制該註解的自動掃描範圍,比如:
@ComponentScan(basePackages = {"cn.codesheep.controller","cn.codesheep.entity"})
可見 這個註解也並不是什麼新東西!
後 記
由於能力有限,若有錯誤或者不當之處,還請大家批評指正,一起學習交流!
作者更多的SpringBt實踐文章在此:
- Spring Boot Admin2.0開箱體驗
- Spring Boot應用監控實戰
- SpringBoot應用部署於外接Tomcat容器
- ElasticSearch搜尋引擎在SpringBt中的實踐
- 初探Kotlin+SpringBoot聯合程式設計
- Spring Boot日誌框架實踐
- SpringBoot優雅編碼之:Lombok加持
如果有興趣,也可以抽點時間看看作者一些關於容器化、微服務化方面的文章:
- 利用K8S技術棧打造個人私有云 連載文章
- 從一份配置清單詳解Nginx伺服器配置
- Docker容器視覺化監控中心搭建
- 利用ELK搭建Docker容器化應用日誌中心
- RPC框架實踐之:Apache Thrift
- RPC框架實踐之:Google gRPC
- 微服務呼叫鏈追蹤中心搭建
- Docker容器跨主機通訊
- Docker Swarm叢集初探
- 高效編寫Dockerfile的幾條準則
可 長按 或 掃描 下面的 小心心 來訂閱 CodeSheep,獲取更多 務實、能看懂、可復現的 原創文 ↓↓↓