-
1 # 梁碼事
-
2 # ksfzhaohui
在瞭解如何設定自動配置註解之前可以先看看spring-boot的自動配置原理,瞭解了原理之後,在來看如何配置就很簡單了;
SpringBoot自動配置
1.自動配置註解
要想使用自動配置功能,SpringBoot提供了註解@EnableAutoConfiguration,當然不需要我們配置因為在@SpringBootApplication註解中預設以及啟用了;
可以看到@SpringBootApplication註解本身也有註解@EnableAutoConfiguration:
在註解@EnableAutoConfiguration中重點看一下@Import註解中使用的AutoConfigurationImportSelector類,此類是自動註解的核心類,會有條件的載入我們預設指定的配置類;這裡有兩個概念一個是有條件,一個是配置類,分別簡單介紹一下:配置類可以簡單理解就是相關元件對接SpringBoot的對接類,此類可以做一些初始化的工作;有條件表示並不是有配置類就能被對接上,是有條件的,SpringBoot預設提供了大量配置類,但並不是所有配置類都能被載入初始化的,是有條件的,比如mybatis在沒有資料來源的情況下,沒有mybatis基礎包的情況下是不能被對接的;下面首先看一下SpringBoot提供的哪些條件類;
2.條件類
SpringBoot提供了很多條件類,可以在配置中上配置註解條件類,相關條件類可以在spring-boot-autoconfigure包下的org.springframework.boot.autoconfigure.condition下找到,主要包含如下:
ConditionalOnBean:當前容器有指定Bean的條件下;ConditionalOnClass:當前類路徑下有指定類的條件下;ConditionalOnCloudPlatform:當指定了雲平臺的時候;ConditionalOnExpression:SpEL表示式作為判斷條件;ConditionalOnJava:JVM版本作為判斷條件;ConditionalOnJndi:在JNDI存在的條件下查詢指定的位置;ConditionalOnMissingBean:當容器裡沒有指定Bean的情況下;ConditionalOnMissingClass:當類路徑下沒有指定的類的條件下;ConditionalOnNotWebApplication:當前專案不是WEB專案的條件下;ConditionalOnProperty:當前應用是否配置了指定屬性指定的值;ConditionalOnResource:只有當指定的資源位於類路徑下;ConditionalOnSingleCandidate:bean工廠中只有一個或者有多個情況下是主要的候選bean;ConditionalOnWebApplication:當前專案是WEB專案的條件下。以上是註解類,註解本身沒有功能,只是提供標記的功能,具體功能在@Conditional中指定的,比如ConditionalOnBean註解如下所示:
相關功能的實現就在OnBeanCondition類中,同樣其他註解類的實現類也在包org.springframework.boot.autoconfigure.condition下找到;
3.自動配置過程
Springboot應用啟動過程中使用ConfigurationClassParser分析配置類,此類中有一個processImports方法,此方法用來處理@Import註解,在@EnableAutoConfiguration註解存在@Import註解,這時候會例項化註解中的AutoConfigurationImportSelector,在其內部有一個AutoConfigurationGroup內部類,內部類有兩個核心方法分別是:process和selectImports;
此方法主要獲取經過條件過濾之後可用的自動配置類,主要呼叫AutoConfigurationImportSelector中的getAutoConfigurationEntry完成的:
透過SpringFactoriesLoader獲取類路徑下META-INF/spring.factories檔案中key為org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置類,可以看一下spring-boot-autoconfigure.jar中的spring.factories內容:
當然這裡只是截取了其中一個類路徑jar下的部分配置,獲取所有配置類之後進行去重,去被排除的類,然後進行條件過濾,下面重點看一下:
此方法大致就是首先獲取配置的AutoConfigurationImportFilter ,然後對之前獲取的所有配置類進行過濾,最後返回過濾之後的配置類;AutoConfigurationImportFilter同樣也是透過SpringFactoriesLoader類進行載入類路徑下META-INF/spring.factories,只不過當前的key是:org.springframework.boot.autoconfigure.AutoConfigurationImportFilter,可以看一下SpringBoot預設配置的filter:
可以看到Filter其實就是上文介紹的條件類,這裡默認了OnBeanCondition,OnClassCondition以及OnWebApplicationCondition,已這裡使用的Mybatis為例看一下MybatisAutoConfiguration的註解:
可以看到其中有用到@ConditionalOnClass,表示必須提供SqlSessionFactory和SqlSessionFactoryBean類的情況下才載入此配置類,而整兩個是正式Mybatis基礎包中提供的;有了基礎包還不行,還需要DataSource,而且DataSource必須在MybatisAutoConfiguration例項化之前初始化好,SpringBoot是如何實現,繼續看另外一個核心方法selectImports():
首先是對被排除類的一個過濾,然後接下來重點看一下對配置類進行排序的一個方法,具體操作在類AutoConfigurationSorter中進行的,具體方法為getInPriorityOrder():
首先使用order進行排序,然後使用@AutoConfigureBefore和@AutoConfigureAfter就行排序;order其實就是透過註解@AutoConfigureOrder進行排序的,值是一個整數,結構類似如下:
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureBefore和@AutoConfigureAfter字面意思也很好理解,指定在其他配置類之前和之後,所以可以看到在MybatisAutoConfiguration中有如下配置:
表示在DataSourceAutoConfiguration配置類載入之後才會載入Mybatis配置類,這樣就解決了依賴關係;還有上文提到的Mybatis操作資料庫依賴的SqlSessionFactory和SqlSession,都在MybatisAutoConfiguration進行了初始化操作;SpringBoot本身其實以及提供了大量常用元件的自動配置類,我們只需要提供滿足的特定條件,SpringBoot自動會幫我載入初始化等操作;
下面用一個簡單的例項來看看如何自定義一個自動配置類;
自定義配置類
接下來我們用很簡單的例項來看一下自定義的流程,一個格式化大寫訊息的例項;
1.pom檔案引入依賴
Spring 官方 Starter通常命名為spring-boot-starter-{name}如 spring-boot-starter-web,Spring官方建議非官方Starter命名應遵循{name}-spring-boot-starter的格式;
2.服務類和屬性配置類
屬性類提供了type引數可以在application.properties中配置,可配置值包括:upper,lower;
3.自動配置類和建立spring.factories檔案
這個就是自定義的自動配置類,SpringBoot啟動的時候會根據條件自動初始化;最後在resources/META-INF/下建立spring.factories檔案:
4.測試
在其他SpringBoot中可以引入上面建立的專案,引入方式也很簡單:
同時在application.properties配置格式化型別:
啟動應用,瀏覽器訪問http://localhost:8888/format?word=hello,結果為:HELLO
更多可以參考本人之前的文章:https://www.toutiao.com/i6749752249532023309/
回覆列表
首先springboot零配置讓開發人員可以快速搭建專案,讓現在的java專案基本都基於springboot來開發了,而很多公司也都有自己的一個或多個springboot starter,這些就是基礎的環境專案,新的專案都引入基礎專案的依賴,然後在新專案中可以使用基礎專案的配置等。這就是我理解的自定義的starter自動配置。下面給你我公司的實現。
第一,在pom檔案中加入基礎starter的依賴,如下圖:
第二,在新專案的主函式入口中,把基礎專案的入口類當引數加進去:
以上是我們的實現,這樣就可以實現自動以的starter實現自動配置,新專案會根據配置自動掃描基礎專案中的配置並載入。