編寫自己的Spring-Boot的statrter
部分內容引用來源聲明:
飛污熊博客 https://www.xncoding.com/2017/07/22/spring/sb-starter.html
-
【概念理解】starter是一種服務——使得使用某個功能的開發者不需要關注各種依賴庫的處理,不需要具體的配置信息, 由Spring Boot自動通過classpath路徑下的類發現需要的Bean,並織入相應的Bean。舉個栗子,spring-boot-starter-jdbc這個starter的存在, 使得我們只需要在BookPubApplication下用@Autowired引入DataSource的bean就可以,Spring Boot會自動創建DataSource的實例。(記住啦,是一個服務,service, starter is a service)
-
【關於配置的好習慣】
@ConfigurationProperties註解的類會被spring-boot-configuration-processor檢測,spring-boot-configuration-processor 的作用是編譯時生成spring-configuration-metadata.json, 此文件主要給IDE使用,用於提示使用。如在intellij idea中,當配置此jar相關配置屬性在application.yml, 你可以用ctlr+鼠標左鍵,IDE會跳轉到你配置此屬性的類中。這個是附加功能,對starter的用戶友好。我爲人人,人人爲我。 -
【關於命名】這裏說下artifactId的命名問題,Spring 官方 Starter通常命名爲spring-boot-starter-{name} 如 spring-boot-starter-web。Spring官方建議非官方Starter命名應遵循{name}-spring-boot-starter的格式。
-
【要素】
- 編寫service類實現,
- 編寫ServiceProperties,要用@ConfigurationProperties註解聲明一下,這樣Spring就會根據註解讀取application.yml的配置,根據配置創建這個ServiceProperties的Bean實例。
- 編寫AutoConfigure,用於控制Bean的初始化創建工作(這個類似編寫application-context.xml, 但是他比application多一個功能,那就是可以通過@Conditional這些條件註解,進行控制是否開啓。因爲Spring-Boot強調的是約定優先,事先約定條件,進行默認配置。不要動不動就得重新配置)
- 在resources/META-INF/創建spring.factories文件,文件內容如下,由於SpringBoot啓動的時候不會掃描AutoConfigure類(Bean創建用的上下文),而是掃描所有Jar包的【resources/META-INF/】目錄,然後纔會加載AutoConfigure類,並初始化Service實例。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xncoding.starter.config.ExampleAutoConfigure
完整代碼如下:
<dependencies>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs)
生成spring-configuration-metadata.json類,需要引入此類-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
// 編寫服務類
public class ExampleService {
private String prefix;
private String suffix;
public ExampleService(String prefix, String suffix) {
this.prefix = prefix;
this.suffix = suffix;
}
public String wrap(String word) {
return prefix + word + suffix;
}}
// 編寫配置模板類
@ConfigurationProperties("example.service")
public class ExampleServiceProperties {
private String prefix;
private String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
// 編寫Spring上下文類
@Configuration@ConditionalOnClass(ExampleService.class)@EnableConfigurationProperties(ExampleServiceProperties.class)public class ExampleAutoConfigure {
private final ExampleServiceProperties properties;
@Autowired
public ExampleAutoConfigure(ExampleServiceProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service", value = "enabled",havingValue = "true")
ExampleService exampleService (){
return new ExampleService(properties.getPrefix(),properties.getSuffix());
}
}
// 添加meta文件到resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xncoding.starter.config.ExampleAutoConfigure
// mvn:install 打包安裝
// 測試過程
// 引入starter
<dependency>
<groupId>com.xncoding</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
// 編寫 application.yml 配置
example.service:
enabled: true
prefix: ppp
suffix: sss
// main方法
@RunWith(SpringRunner.class)@SpringBootTestpublic class ApplicationTests {
@Autowired
private ExampleService exampleService;
@Test
public void testStarter() {
System.out.println(exampleService.wrap("hello"));
}
}
- 【關鍵知識點,必看】@ConditionalOnMissingBean配置註解的類,可以被重寫(也就可以重新定義類的初始化,比如默認是單例的Bean可以改成多例,又或者默認的application.yml參數滿足你的需求,你也可以重新搞一個)