starter背景
Spring Boot目前已經變成了後端開發這必備技能之一,其中一個主要緣由是Spring Boot中有個很是重要的機制(starter機制)。java
starter可以拋棄之前繁雜的配置,將其統一集成進starter,使用的時候只須要在maven中引入對應的starter依賴便可,Spring Boot就能自動掃描到要加載的信息並啓動相應的默認配置。spring
starter讓咱們擺脫了各類依賴庫的處理,以及各類配置信息的煩惱。SpringBoot會自動經過classpath路徑下的類發現須要的Bean,並註冊進IOC容器。Spring Boot提供了針對平常企業應用研發各類場景的spring-boot-starter依賴模塊。全部這些依賴模塊都遵循着約定成俗的默認配置,並容許咱們調整這些配置,即遵循「約定大於配置」的理念。編程
咱們常常會看到或者使用到各類xxx-starter。好比下面幾種:json
Spring Boot starter原理
從整體上來看,無非就是將Jar包做爲項目的依賴引入工程。而如今之因此增長了難度,是由於咱們引入的是Spring Boot Starter,因此咱們須要去了解Spring Boot對Spring Boot Starter的Jar包是如何加載的?下面我簡單說一下。後端
SpringBoot 在啓動時會去依賴的 starter 包中尋找 /META-INF/spring.factories 文件,而後根據文件中配置的 Jar 包去掃描項目所依賴的 Jar 包,這相似於 Java 的 SPI 機制。app
細節上可使用@Conditional 系列註解實現更加精確的配置加載Bean的條件。maven
JavaSPI 其實是「基於接口的編程+策略模式+配置文件」組合實現的動態加載機制。spring-boot
自定義starter的條件
若是想自定義Starter,首選須要實現自動化配置,而要實現自動化配置須要知足如下兩個條件:this
-
可以自動配置項目所須要的配置信息,也就是自動加載依賴環境;url
-
可以根據項目提供的信息自動生成Bean,而且註冊到Bean管理容器中;
實現自定義starter
pom.xml依賴
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.0.0.RELEASE</version> <optional>true</optional> </dependency> </dependencies>
根據須要自定義Starter的實現過程大體以下(以我定義的Starter爲例):
定義XxxProperties類,屬性配置類,完成屬性配置相關的操做,好比設置屬性前綴,用於在application.properties中配置。
TianProperties代碼:
import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "spring.tian") public class TianProperties { private String name; private int age; private String sex = "M"; //省略 get set 方法 }
建立XxxService類,完成相關的操做邏輯 。
TianService代碼:
public class TianService { private TianProperties properties; public TianService() { } public TianService(TianProperties userProperties) { this.properties = userProperties; } public void sayHello(){ System.out.println("hi, 我叫: " + properties.getName() + ", 今年" + properties.getAge() + "歲" + ", 性別: " + properties.getSex()); } }
定義XxxConfigurationProperties類,自動配置類,用於完成Bean建立等工做。
TianServiceAutoConfiguration代碼:
@Configuration @EnableConfigurationProperties(TianProperties.class) @ConditionalOnClass(TianService.class) @ConditionalOnProperty(prefix = "spring.tian", value = "enabled", matchIfMissing = true) public class TianServiceAutoConfiguration { @Autowired private TianProperties properties; @Bean @ConditionalOnMissingBean(TianService.class) public TianService tianService() { return new TianService(properties); } }
在resources下建立目錄META-INF,在 META-INF 目錄下建立 spring.factories,在SpringBoot啓動時會根據此文件來加載項目的自動化配置類。
「spring.factories中配置」
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.tian.TianServiceAutoConfiguration
把上面這個starter工程打成jar包:
使用自定義starter
建立一個Spring Boot項目test,項目總體以下圖:
在項目中把自定義starter添加pom依賴
<dependency> <groupId>com.tian</groupId> <artifactId>spring-boot-tian-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
TestApplication啓動類
@SpringBootApplication @EnableEurekaServer public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
application.properties中配置
spring.tian.name=tian spring.tian.age=22 spring.tian.sex=M
寫一個TestController.java類
RestController @RequestMapping("/my") public class TestController { @Resource private TianService tianService; @PostMapping("/starter") public Object starter() { tianService.sayHello(); return "ok"; } }
把咱們自定義的starter打成的jar依賴進來後,
能夠看到其中多了一個json的文件。
最後啓動項目,輸入
http://localhost:9091/my/starter
controller成功返回ok,再看後臺打印
hi, 我叫: tian, 今年22歲, 性別: M
這就成功的現實了自定義的starter。
關鍵詞:開箱即用、減小大量的配置項、約定大於配置。
總結
-
Spring Boot在啓動時掃描項目所依賴的JAR包,尋找包含spring.factories文件的JAR包,
-
而後讀取spring.factories文件獲取配置的自動配置類AutoConfiguration`,
-
而後將自動配置類下知足條件(@ConditionalOnXxx)的@Bean放入到Spring容器中(Spring Context)
-
這樣使用者就能夠直接用來注入,由於該類已經在容器中了。
「只要咱們的方向對了,就不怕路遠!」