spring-boot-starter的核心就是依賴管理、約定配置、自動裝配。
依賴管理:starter模塊會將它所需要的依賴自動引入,項目無需再引入。
約定配置:starter會定義它所需要的配置項,同時會給這些配置項默認值。如果你使用默認配置,則項目無需再配置;如果你使用默認配置,則項目屬性文件添加自己的配置項即可。
自動裝配:starter模塊中的AutoConfiguration會自動根據定義的配置項做一些初始化的工作,如初始化Bean到spring容器。
在實際應用中,我們可以自定義 starter 來實現項目中復用度高的業(yè)務,讓別的模塊能很方便的引入使用。
下面我們來編寫一個簡單的stater。參照mybatis的starter結構,starter由兩個部分構成:starter和autoconfigure。starter里面沒有內容,但pom里面引入了autoconfigure,主要是一個依賴傳遞,起了依賴保護的作用;autoconfigure里面才是真正實現功能的地方。
參照此結構,我們建一個hello的starter,包含兩個工程:hello-spring-boot-autoconfigure和hello-spring-boot-starter。

一、hello-spring-boot-autoconfigure
創(chuàng)建hello-spring-boot-autoconfigure工程,pom.xml引入自動裝配需要的依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-boot-autoconfigure</name>
<description>這是一個自定義的springboot的starter</description>
<properties>
<java.version>1.8</java.version>
<boot.version>2.2.5.RELEASE</boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${boot.version}</version>
</dependency>
</dependencies>
</project>
編寫屬性配置類,將配置文件中的屬性綁定到該類中的屬性
@ConfigurationProperties(prefix = "spring.hello")
public class HelloProperties {
private String name = "Jancen";
private int age = 10;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
編寫業(yè)務類實現功能,在使用時供項目調用
public class HelloService {
private HelloProperties properties;
public void setProperties(HelloProperties properties) {
this.properties = properties;
}
public String hello(){
Random random = new Random();
return properties.getName() + ",你的編號是" + random.nextInt(properties.getAge());
}
}
自動裝配類,使配置生效,并且把服務注入到容器中
@Configuration
@EnableConfigurationProperties(HelloProperties.class)//使配置文件生效
@ConditionalOnClass(HelloService.class)//classpath存在指定類時自動裝配
@ConditionalOnProperty(prefix = "spring.hello", value = "enabled", matchIfMissing = true)//當配置文件中example.service.enabled=true時進行自動配置,默認為true。
public class HelloAutoConfiguration {
@Autowired
private HelloProperties properties;
//注入bean實例
@Bean
@ConditionalOnMissingBean(HelloService.class)//當Spring Context中有指定的Bean的條件下
public HelloService helloService(){
HelloService service = new HelloService();
service.setProperties(properties);
return service;
}
}
在 src/main/resource/META-INF目錄下創(chuàng)建一個配置文件 spring.factories,指定自動裝配的類,這個是重點。spring-core中的SpringFactoriesLoader通過檢索這個文件中的內容,獲取到指定的配置類。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.jancen.starter.configure.HelloAutoConfiguration
以上starter就創(chuàng)建完成了,使用maven install打成jar包。
二、hello-spring-boot-starter
創(chuàng)建hello-spring-boot-starter工程,pom引入hello-spring-boot-autoconfigure依賴。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-boot-starter</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
好了,starter項目創(chuàng)建好了。其他什么多余的代碼都不要,統(tǒng)統(tǒng)刪掉。
使用maven install將starter達成jar包。
三、測試使用starter
創(chuàng)建測試工程,在pom里面映入我們自己的starter的依賴,使用starter里面初始化的HelloService這個Bean。
<dependency>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
編寫測試類,測試HelloService
@SpringBootTest
class HelloStarterTestApplicationTests {
@Autowired
private HelloService helloService;
@Test
void testHello() {
System.out.println(helloService.hello());
}
}
當我們application.properties文件里面什么配置都沒有的時候,name和age配置項使用的是默認值,打印出來的日志如下:
2020-03-13 15:30:13.219 INFO 5944 --- [ main] c.j.t.HelloStarterTestApplicationTests :
Jancen,你的編號是7
當我們在application.properties自定義配置項的值時:
spring.hello.name=Hanmeimei
spring.hello.age=20
spring.hello.enabled=true
打印日志:
2020-03-13 15:36:26.030 INFO 10996 --- [ main] c.j.t.HelloStarterTestApplicationTests :
Hanmeimei,你的編號是9
說明項目成功調用starter中自定義的業(yè)務方法,并獲取到了綁定的屬性值。
四、最后
starter的自動裝配特性在實際項目中非常有用。例如,項目要集成cache緩存框架,但是緩存框架有很多,不同項目可能使用不同的緩存框架。可以通過自己編寫starter來自動識別集成哪個緩存框架,類似于jdbcTemplate。