Spring?Boot?中starter的原理詳析
前言:
今天介紹springboot ,也是寫下springboot的插件機(jī)制,starter的原理,其實(shí)這個網(wǎng)上已經(jīng)很多了,也是看了不少別人的文章,今天主要還是帶著問題去記錄下。
1、springboot 的starter 的啟動原理是什么
原理
這個問題是很簡單的,只要了解springboot的同學(xué)應(yīng)該都知道,也是必須了解的。
- ① Spring Boot 在啟動時會去classpath中中尋找 resources/META-INF/spring.factories 文件
- ② 根據(jù) spring.factories 配置加載 AutoConfigure 類
- ③ 根據(jù) @Conditional 注解的條件,進(jìn)行自動配置并將 Bean 注入 Spring Context
來個例子
我們看個例子,下面是我工作中的一個starter,刪除了一些公司的代碼
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.xx.common.ratelimiter.config.reactive.WebsocketRateLimiterAutoConfiguration,\ com.xx.common.ratelimiter.config.ProductIdLimiterAutoConfiguration
解釋下:
- EnableAutoConfiguration 這個是固定的,在springboot啟動的時候,會去實(shí)例化這個key之后的每一個類
- \ 是連接符,也就是表示這是一行數(shù)據(jù),只不過可以分行表示
- WebsocketRateLimiterAutoConfiguration 后面這兩行是業(yè)務(wù)自定義的config類,多個的話都好分割
@Configuration @ConditionalOnProperty( prefix = "gateway.ratelimiter", name = {"enabled"}, havingValue = "true" ) @EnableConfigurationProperties(RateLimiterProperties.class) @AutoConfigureAfter({RedisAutoConfiguration.class}) public class ProductIdLimiterAutoConfiguration { ... }
上面這個是配置類,可以看到這個最主要的是一些注解
- @Configuration 標(biāo)識這是一個配置類
- @ConditionalOnProperty 標(biāo)識這個類的實(shí)例化需要在配置文件中存在 gateway.ratelimiter.enable 這個key,并且值為true
- @EnableConfigurationProperties 將配置中的類,讀取到RateLimiterProperties.class 這個對象中
- @AutoConfigureAfter 這個顧名思義,需要在redis 的實(shí)例化之后,因?yàn)檫@個config依賴redis 。
小結(jié)
springboot starter的原理就是springboot項(xiàng)目在啟動的時候掃描jar,然后讀取spring.factories 中EnableAutoConfiguration key 指向的config類
然后通過一系列的條件配置判斷,啟動當(dāng)前stater
2、springboot 是如何找到配置類的
第一個問題解決了主要流程的問題,但是springboo是怎么找到spring.fatories的吶、?
這個主要是涉及jar包中資源的讀取,讓我們看下這個流程。
主要的路徑是下面這三個注解:
SpringBootApplication -> EnableAutoConfiguration -> AutoConfigurationImportSelector org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames org.springframework.core.io.support.SpringFactoriesLoader#loadSpringFactories Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION); public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
通過上面的路徑,我們找到了最終是通過classloader 加載jar中"META-INF/spring.factories";當(dāng)然這段是代碼我們也可以用來加載其他的文件哦,也給我們借鑒,在下次需要實(shí)現(xiàn)類似的功能,可以直接抄。
3、springboot starter 的bean 是怎么加載到容器的
這個問題已經(jīng)很簡單了,因?yàn)榈谝粋€問題已經(jīng)基本上可以看到原因了,
在springboot 加載到config的時候,可以在config中通過@bean進(jìn)行容器注冊,這個bean就會加載到容器
這里主要要說幾個特殊的注解,@ConditionalOnXXX
- @ConditionalOnBean:當(dāng)容器中有指定Bean的條件下進(jìn)行實(shí)例化。
- @ConditionalOnMissingBean:當(dāng)容器里沒有指定Bean的條件下進(jìn)行實(shí)例化。
- @ConditionalOnClass:當(dāng)classpath類路徑下有指定類的條件下進(jìn)行實(shí)例化。
- @ConditionalOnMissingClass:當(dāng)類路徑下沒有指定類的條件下進(jìn)行實(shí)例化。
- @ConditionalOnWebApplication:當(dāng)項(xiàng)目是一個Web項(xiàng)目時進(jìn)行實(shí)例化。
- @ConditionalOnNotWebApplication:當(dāng)項(xiàng)目不是一個Web項(xiàng)目時進(jìn)行實(shí)例化。
- @ConditionalOnProperty:當(dāng)指定的屬性有指定的值時進(jìn)行實(shí)例化。
- @ConditionalOnExpression:基于SpEL表達(dá)式的條件判斷。
- @ConditionalOnJava:當(dāng)JVM版本為指定的版本范圍時觸發(fā)實(shí)例化。
- @ConditionalOnResource:當(dāng)類路徑下有指定的資源時觸發(fā)實(shí)例化。
- @ConditionalOnJndi:在JNDI存在的條件下觸發(fā)實(shí)例化。
- @ConditionalOnSingleCandidate:當(dāng)指定的Bean在容器中只有一個,或者有多個但是指定了首選的Bean時觸發(fā)實(shí)例化。
如果想要定制自己的condition,可以實(shí)現(xiàn)Condition接口,定制Condition條件
4、總結(jié)
springboot starter 是springboot 的核心,提供了autoconfig,在開發(fā)中非常方便,也是必須需要了解的。
到此這篇關(guān)于Spring Boot 中starter原理詳析的文章就介紹到這了,更多相關(guān)Spring Boot starter 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入理解Java線程池從設(shè)計(jì)思想到源碼解讀
這篇文章主要介紹了深入理解Java線程池從設(shè)計(jì)思想到源碼解讀,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03SpringBoot中的@Configuration、@MapperScan注解
SpringBoot中的@Configuration和@MapperScan注解分別用于配置類和Mapper接口的自動掃描,感興趣的朋友跟隨小編一起看看吧2024-11-11DynamicDataSource怎樣解決多數(shù)據(jù)源的事務(wù)問題
這篇文章主要介紹了DynamicDataSource怎樣解決多數(shù)據(jù)源的事務(wù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Mybatis Mybatis-Plus傳入多個參數(shù)的處理方式
這篇文章主要介紹了Mybatis Mybatis-Plus傳入多個參數(shù)的處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-0525行Java代碼將普通圖片轉(zhuǎn)換為字符畫圖片和文本的實(shí)現(xiàn)
這篇文章主要介紹了25行Java代碼將普通圖片轉(zhuǎn)換為字符畫圖片和文本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04springboot的http.server.requests服務(wù)請求流程源碼
這篇文章主要為大家介紹了springboot的http.server.requests服務(wù)請求流程源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12Spring的循環(huán)依賴、三級緩存解決方案源碼詳細(xì)解析
這篇文章主要介紹了Spring的循環(huán)依賴、三級緩存解決方案源碼詳細(xì)解析,在Spring中,由于IOC的控制反轉(zhuǎn),創(chuàng)建對象不再是簡單的new出來,而是交給Spring去創(chuàng)建,會經(jīng)歷一系列Bean的生命周期才創(chuàng)建出相應(yīng)的對象,需要的朋友可以參考下2024-01-01