starter如何設置自動配置注解?
在了解如何設置自動配置注解之前可以先看看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
以上分析了一下springboot的自動配置原理,并自定義一個自動配置類,并且運行,相信對你有所幫助;
更多可以參考本人之前的文章:https://www.toutiao.com/i6749752249532023309/