在springboot啟動流程的系列文章中,我們看過了springboot的自動配置機制,本文將基於自動配置機制自定義一個自動配置的starter示例
正文
模塊結構
首先,我們准備兩個模塊service和web,模塊結構如
service模塊
在service模塊中,我們添加一個服務類TestService
public class TestService { public String getName() { return "lay"; } }
接着再添加一個ServiceAutoConfiguration配置類,將TestService變成一個Bean
public class ServiceAutoConfiguration { @Bean public TestService testService() { return new TestService(); } }
還有最重要的一步,將ServiceAutoConfiguration添加到META-INF/spring.factories中成為自動配置類
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.lay.service.ServiceAutoConfiguration
這樣,service就完畢了,我們看看service模塊的結構
web模塊
我們先在web的pom.xml文件中添加service的模塊依賴
<dependency> <groupId>cn.lay</groupId> <artifactId>service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
再添加一個TestController
@RestController
public class TestController {
@Autowired
private TestService testService;
@GetMapping("getName")
public String getName() {
return testService.getName();
}
}
啟動測試
當我們啟動web以后,會根據service的META-INF/spring.factories中配置的自動配置類把TestService變成Bean,然后注入到TestController中
我們打開瀏覽器測試一下
可以看到,我們成功執行獲得結果
添加條件化注解
在META-INF/spring.factories中添加配置類,但是很多時候我們希望配置類在滿足一些條件的時候才生效,為此我們可以使用@Conditional注解或者組合了@Conditional注解的注解
本例中,我們將在ServiceAutoConfiguration中使用使用@ConditionalOnClass注解,該注解表示當某個類存在的時候配置類才生效
@ConditionalOnClass(name = "java.lang.String")
public class ServiceAutoConfiguration {
@Bean
public TestService testService() {
return new TestService();
}
}
注解中指明,當String類存在的時候ServiceAutoConfiguration才會進行解析處理,而如果你指明一個不存在的類,如:java.lang.String2,那么TestService將不會被解析成一個Bean
添加properties
我們先在service模塊的pom.xml中添加properties處理依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
添加一個配置屬性對象
@ConfigurationProperties(prefix = "service") public class ServiceProperties { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "ServiceProperties{" + "name='" + name + '\'' + '}'; } }
在ServiceAutoConfiguration添加為Bean,開啟屬性自動解析
@ConditionalOnClass(name = "java.lang.String") @EnableConfigurationProperties(value = {ServiceProperties.class}) public class ServiceAutoConfiguration { @Bean public TestService testService() { return new TestService(); } }
把ServiceProperties注入到TestService中
public class TestService { @Autowired private ServiceProperties serviceProperties; public String getName() { return serviceProperties.getName(); } }
回到web模塊,在application.properties中添加配置
service.name=lay
重新啟動測試,你會看到瀏覽器獲取到了結果
總結
springboot的自動配置,其實就是包了一層自動發現(spi機制)的spring.factories配置,然后通過@Conditional相關的條件化處理來決定是否進行配置類的解析工作。