spring-boot-*-starter
對於spring的項目,我們大多數情況下需要完成的工作是如何將對象註冊到spring容器中,由容器完成對象依賴關係的管理,然後我們從容器中安類型或名稱取出實例進行使用。
如今在項目變得愈發的龐大複雜的情況下,我們一般會將一個大項目按照模塊、業務等進行拆分,看spring frameworker 就可以知道,其核心由多個模塊構成,同時衍生出很多的模塊與其它框架進行整合與擴展,那麼回到上面的問題,如何將擴展的模塊關係的bean交給spring ico,我們可以看到有很多的spring-boot-*-starter類似的jar。
先回憶一下,在之前springmvc時代,如果項目中我們有多個模塊是如何實現,是否需要給每個模塊配置一個applicationContext.xml,然後在主模塊中通過import引入各個子模塊的xml。現在沒有了xml我們怎麼實現這個?
在對starter瞭解之前,有必要知道一個東西,SPI(Service Provider Interface),這個不屬於spring,而是由java提供的一套“接口+策略模式+配置文件”實現動態加載的機制。簡單的說就是通過反射技術,實現了接口(抽象)與實現的解耦。
示例:
1、定義接口 InfoProvider
2、在classpath,也就是src/main/resources中新建目錄META-INF/services
3、在上一目錄創建文件,命名InfoProvider全限名 com.sucl.starter.spi.InfoProvider
4、寫兩個InfoProvider的實現類StaticInfoProvider、ClassInfoProvider
5、分別將以上兩個實現的全名寫入com.sucl.starter.spi.InfoProvider文件中
6、通過ServiceLoader獲取實現
7、Junit測試
大致瞭解了SPI後再看看springboot中的使用,在spring-boot-autoconfigure中,META-INF/spring.factories,這個可以說是spring spi,與上面ServiceLoader對應SpringFactoriesLoader,實現上都是通過反射,只不過spring功能更強大。
可以看到,該類主要提供了幾個靜態方法,得以在根據需要將spring.factories中定義的接口實現在不同環境下進行處理。
在spring.factories中可以看到很多默認的策略,比如我們EnableAutoConfiguration對應了很多auto相關的實現,具體細節如何實現可以閱讀源碼。
現在我們有一個新的模塊,如何與我們項目關聯,如果單純的將模塊打成jar引入到項目,你會發現,該模塊中的bean是沒辦法注入當前項目的容器中,那麼我們可以做個測試
示例:
1、新建模塊spring-boot-simple-starter
2、創建一個簡單的服務SimpleService、實現SimpleServiceImpl,創建bean的配置文件SimpleAutoConfiguration將服務註冊到IOC
3、在src/main/resources下創建META-INF/spring.factories,寫入
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.sucl.simplestarter.SimpleAutoConfiguration
4、在本pom.xml中引入剛的模塊
5、Junit測試
通過這樣的方式,springboot得以實現將一些內置的配置項通過spi的模式注入到spring中,同時對於後期的維護也比較靈活。
總結:springboot starter主要完成依賴模塊注入到spring ioc