您好,登錄后才能下訂單哦!
如何理解SpringBoot核心運行原理和運作原理源碼,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
Spring Boot 最核心的功能就是自動配置,第 1 章中我們已經提到,功能的實現都是基于“約定優于配置”的原則。那么 Spring Boot 是如何約定,又是如何實現自動配置功能的呢?
本章會帶領大家通過源碼學習 Spring Boot 的核心運作原理,內容涉及自動配置的運作原理、核心功能模塊、核心注解以及使用到的核心源代碼分析。
核心運行原理
使用 Spring Boot 時,我們只需引|入對應的 Starters, Spring Boot 啟動時便會自動加載相關依賴,配置相應的初始化參數,以最快捷、簡單的形式對第三方軟件進行集成,這便是 SpringBoot 的自動配置功能。我們先從整體上看一下 Spring Boot 實現該運作機制涉及的核心部分,如圖 2-1 所示。
圖 2-1 描述了 Spring Boot 自動配置功能運作過程中涉及的幾個核心功能及其相互之間的關系包括@EnableAutoConfiguration、spring.factories、各組件對應的 AutoConfiguration 類、@Conditional 注解以及各種 Starters。
可以用一句話來描述整個過程:Spring Boot 通過@EnableAutoConfiguration 注解開啟自動配置,加載 spring.factories 中注冊的各種 AutoConfiguration 類,當某個 AutoConfiguration類滿足其注解@Conditional 指定的生效條件(Starters 提供的依賴、配置或 Spring 容器中是否存在某個 Bean 等)時,實例化該 AutoConfiguration 類中定義的 Bean(組件等),并注入 Spring 容器,就可以完成依賴框架的自動配置。
我們先從概念及功能上了解一下圖 2-1 所示部分的作用及相互關系,在后面章節中會針對每個功能及組件進行源代碼級別的講解。
·@EnableAutoConfiguration:該注解由組合注解@SpringBootApplication 引入,完成自動配置開啟,掃描各個jar包下的spring.factories文件,并加載文件中注冊的AutoConfiguration類等。
·spring.factories:配置文件,位于 jar 包的 META-INF 目錄下,按照指定格式注冊了自動配置的 AutoConfiguration 類。spring.factories 也可以包含其他類型待注冊的類。該配置文件不僅存在于 Spring Boot 項目中,也可以存在于自定義的自動配置(或 Starter)項目中。
·AutoConfiguration 類:自動配置類,代表了 Spring Boot 中一類以 XXAutoConfiguration命名的自動配置類。其中定義了三方組件集成 Spring 所需初始化的 Bean 和條件。
·@Conditional:條件注解及其衍生注解,在 AutoConfiguration 類上使用,當滿足該條件注解時才會實例化 AutoConfiguration 類。
·Starters:三方組件的依賴及配置,Spring Boot 已經預置的組件。Spring Boot 默認的Starters 項目往往只包含了一個 pom 依賴的項目。如果是自定義的 starter,該項目還需包含 spring.factories 文件、AutoConfiguration 類和其他配置類。
以上在概念層面介紹了 Spring Boot 自動配置的整體流程和基本運作原理,下面將會詳細介紹這幾個核心部分的組成結構及源代碼。
@EnableAutoConfiguration 是開啟自動配置的注解,在創建的 SpringBoot 項目中并不能直接看到此注解,它是由組合注解@SpringBootApplication 引入的。下面我們先來了解一下 入口類和@SpringBootApplication 注解的功能,然后再深入了解@EnableAutoConfiguration注解的構成與作用。
入口類和@SpringBootApplication 注解
Spring Boot 項目創建完成會默認生成-個*Application 的入口類。 在默認情況下,無論是通過 IDEA 還是通過官方創建基于 Maven 的 Spring Boo 項目,入口類的命名規則都是artifactld+Application。通過該類的 main 方法即可啟動 Spring Boot 項目,代碼如下。
@SpringBootApplication public class SpringLearnApplication { public static void main(String[] args) { SpringApplication. run(DemoApplication. class, args); }}
這里的 main 方法并無特別之處,就是一一個標準的 Java 應用的 main 方法,用于啟動 SpringBoot 項目的入口。在默認情況下,按照上述規則命名并包含 main 方法的類稱為入口類。
在 Spring Boot 入口類(除單元測試外)中,唯一的一個注解就是@SpringBootApp-lication。
它是 Spring Boot 項目的核心注解,用于開啟自動配置,準確說是通過該注解內組合的@EnableAutoConfiguration 開啟了自動配置。
@Target(ElementType . TYPE) @Retent ion(Retent ionPolicy . RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfi guration @ComponentScan( excludeFilters = { @Filter(type = FilterType .CUSTOM, classes = TypeExcludeFilter. class), @Filter(type = FilterType. CUSTOM, classes = AutoConf igurationExcludeFilter . class) })public @interface SpringBootApplication { //排除指定自動配置類 @AliasFor(annotation = EnableAutoConfiguration.class) Class<?>[] exclude() default {}; //排除指定自動配置類名 @AliasFor( annotation = EnableAutoConfiguration. class) String[] excludeName() default { //指定掃描的基礎包,激活炷解組件的初始化 @AliasFor( annotation = ComponentScan. class, attribute = "basePackages") String[] scanBasePackages() default {}; //指定掃描的類,用于初始化 @AliasFor( annotation = ComponentScan. class, attribute = "basePackageClass Class<?>[] scanBasePackageClasses() default {}; //指定是否代理@Bean 方法以強制執行 bean 的生命周期行為 @AliasFor( annotation = Configuration.class) boolean proxyBeanMethods() default true ; }
通過源代碼可以看出,該注解提供了以下成員屬性(注解中的成員變量以方法的形式體現)。
exclude:根據類(Class) 排除指定的自動配置,該成員屬性覆蓋了@SpringBoot-Application中組合的@ EnableAutoConfiguration 中定義的 exclude 成員屬性。
excludeName :根據類名排除指定的自動配置,覆蓋了@ EnableAutoConfiguration 中的excludeName 的成員屬性。
:scanBasePackages:指定掃描的基礎 package,用于激活@Component 等注解類的初始化。
scanBasePackageClasses:掃描指定的類,用于組件的初始化。
:proxyBeanMethods:指定是否代理@ Bean 方法以強制執行 bean 的生命周期行為。此功能需要通過運行時生成 CGLIB 子類來實現方法攔截。該子類有一定的限制,比如配置類及其方法不允許聲明為 final 等。
proxyBeanMethods 的默認值為 true,允許配置類中進行 inter-beanreferences (bean 之 間的引用)以及對該配置的@Bean 方法的外部調用。如果@Bean 方法都是自包含的,并且僅提供了容器使用的普通工程方法的功能,則可設置為 false,避免處理 CGLIB 子類。SpringBoot 2.2 版本上市后新增該成員屬性,后面章節涉及的自動配置類中基本都會用到proxyBeanMethods,一 般情況下都配置為 false。
通過以上源代碼我們會發現,Spring Boot 中大量使用了@AliasFor 注解,該注解用于橋接到其他注解,該注解的屬性中指定了所橋接的注解類。如果點進去查看,會發現@SpringBootApplication 定 義的屬性在其他注解中已經定義過了。之所以使用@AliasFor注解并重新在@SpringBootApplication 中定義,更多是為了減少用戶使用多注解帶來的麻煩。
@SpringBootApplication
注 解 中 組 合 了 @SpringBootConfiguration 、@EnableAutoConfiguration 和@ComponentScan。因此,在實踐過程中也可以使用這 3 個注解來替代@SpringBootApplication。
在 Spring Boot 早期版本中并沒有@SpringBootConfiguration 注解,版本升級后新增了@SpringBootConfiguration 并在其內組合了@Configuration。
@EnableAutoConfiguration 注解組合了@AutoConfigurationPackage.我們忽略掉一些基礎注解和元注解, @SpringBootApplication 注解的組合結構可以參考圖2-2。
在圖2-2中,@SpringBootApplication除 了組合元注解之外,其核心作用還包括:激活SpringBoot 自 動 配 置 的 @EnableAutoConfiguration 、 激 活 @Component 掃 描 的@ComponentScan、激活配置類的@Configuration。
其中@ComponentScan 注解和@Configuration 注解在日常使用 Spring 時經常用到,也非常 基 礎 , 大 家應該都有一些了 解 , 這 里 就 不 再 贅 述 了 。 下 面 詳 細 介 紹@EnableAuto-Configuration 的功能。
在未使用 Spring Boot 的情況下,Bean 的生命周期由 Spring 來管理,然而 Spring 無法自動配置@Configuration 注解的類。而 Spring Boot 的核心功能之- 就是根據約定自動管理該注解標注的類。用來實現該功能的組件之-便是@EnableAutoConfiguration 注解。
@EnableAutoConfiguration 位 于 spring-boot autoconfigure 包 內 , 當 使 用@SpringBootApplication 注解時,@EnableAutoConfiguration 注 解會自動生效。
@EnableAutoConfiguration 的主要功能是啟動 Spring 應用程序上下文時進行自動配置,它會嘗試猜測并配置項目可能需要的 Bean。自動配置通常是基于項目 classpath 中引入的類和已定義的 Bean 來實現的。在此過程中,被自動配置的組件來自項目自身和項目依賴的 jar包中。
舉 個 例 子 : 如 果 將 tomcat-embedded.jar 添 加 到 classpath 下 , 那 么@EnableAutoConfiguration 會認為你準備用 TomcatServletWebServerFactory 類,并幫你初始化相關配置。與此同時,如果自定義了基于 ServletWebServerFactory 的 Bean ,那么@EnableAutoConfiguration 將不會進行 TomcatServletWebServerFactory 類的初始化。這一系列的操作判斷都由 Spring Boot 來完成。
下面我們來看一下@EnableAutoConfiguration 注解的源碼。
@Target(ElementType . TYPE) @Retention( RetentionPolicy . RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConf igurat ionImportSelector. class) public @interface EnableAutoConfiguration { //用來餐蓋配置開啟/關閉自動配置的功能 String ENABLED. OVERRIDE_ PROPERTY = "spring. boot . enableautoconf iguration" ; //根據類(Class) 排除指定的自動配置 Class<?>[] exclude() default {}; //根據類名排除指定的自動配置 String[] excludeName() default {}; }
@EnableAutoConfiguration 注解提供了一-個常量和兩個成員參數的定義。
ENABLED OVERRIDE PROPERTY:用來覆蓋開啟/關閉自動配置的功能。
-exclude:根據類(Class) 排除指定的自動配置。
excludeName:根據類名排除指定的自動配置。
正如上文所說,@EnableAutoConfiguration 會猜 測你需要使用的 Bean,但如果在實戰中你并不需要它預置初始化的 Bean,可通過該注解的 exclude 或 excludeName 參數進行有針對性的排除。比如,當不需要數據庫的自動配置時,可通過以下兩種方式讓其自動配置失效。
//通過@SpringBootAppl ication 排除 DataSourceAutoConfiguration @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)public class SpringLearnApplication {}或://通過@Enabl eAutoConfiguration 排除 DataSourceAutoConfiguration @Configuration@EnableAutoConfiguration( exclude = DataSourceAutoConfiguration. class)public class DemoConfiguration {}
需要注意的是,被@EnableAutoConfiguration 注 解的類所在 package 還具有特定的意義,通常會被作為掃描注解@Entity 的根路徑。這也是在使用@SpringBootApplication 注解時需要將被注解的類放在頂級 package 下的原因,如果放在較低層級,它所在 package 的同級或上級中的類就無法被掃描到。
而 對 于 入 口 類 和 其 main 方 法 來 說 , 并 不 依 賴 @SpringBootApplication 注 解 或@EnableAuto-Configuration 注解,也就是說該注解可以使用在其他類上,而非入口類上。
關于如何理解SpringBoot核心運行原理和運作原理源碼問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。