“眾所周知,,Spring Boot由眾多Starter組成,,隨著版本的推移Starter家族成員也與日俱增。在傳統(tǒng)Maven項(xiàng)目中通常將一些層,、組件拆分為模塊來(lái)管理,,以便相互依賴復(fù)用,在Spring Boot項(xiàng)目中我們則可以創(chuàng)建自定義Spring Boot Starter來(lái)達(dá)成該目的,。
好,,開(kāi)始,先創(chuàng)建一個(gè)Maven項(xiàng)目并引入依賴,,pom.xml
如下,,供參考~
<?xml version='1.0' encoding='UTF-8'?>
<project xmlns='http://maven./POM/4.0.0'
xmlns:xsi='http://www./2001/XMLSchema-instance'
xsi:schemaLocation='http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd'>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
這里說(shuō)下artifactId
的命名問(wèn)題,Spring 官方 Starter通常命名為spring-boot-starter-{name}
如 spring-boot-starter-web
,, Spring官方建議非官方Starter命名應(yīng)遵循{name}-spring-boot-starter
的格式,。
這里講一下我們的Starter要實(shí)現(xiàn)的功能,很簡(jiǎn)單,,提供一個(gè)Service
,,包含一個(gè)能夠?qū)⒆址由锨昂缶Y的方法String wrap(String word)
。
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;
}
}
前綴,、后綴通過(guò)讀取application.properties(yml)
內(nèi)的參數(shù)獲得
@ConfigurationProperties('example.service')
public class ExampleServiceProperties {
private String prefix;
private String suffix;
//省略 getter setter
重點(diǎn),,編寫AutoConfigure
類
@Configuration
@ConditionalOnClass(ExampleService.class)
@EnableConfigurationProperties(ExampleServiceProperties.class)
public class ExampleAutoConfigure {
@Autowired
private ExampleServiceProperties properties;
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = 'example.service',value = 'enabled',havingValue = 'true')
ExampleService exampleService (){
return new ExampleService(properties.getPrefix(),properties.getSuffix());
}
}
解釋下用到的幾個(gè)和Starter相關(guān)的注解:
@ConditionalOnClass
,當(dāng)classpath
下發(fā)現(xiàn)該類的情況下進(jìn)行自動(dòng)配置,。@ConditionalOnMissingBean
,,當(dāng)Spring Context
中不存在該Bean
時(shí)。@ConditionalOnProperty(prefix = 'example.service',value = 'enabled',havingValue = 'true')
,,當(dāng)配置文件中example.service.enabled=true
時(shí),。
更多相關(guān)注解,建議閱讀官方文檔該部分,。
最后一步,,在resources/META-INF/
下創(chuàng)建spring.factories
文件,內(nèi)容供參考下面~
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autocinfigure.ExampleAutoConfigure
OK,,完事,,運(yùn)行 mvn:install
打包安裝,一個(gè)Spring Boot Starter便開(kāi)發(fā)完成了,。如果你需要該Starter的源代碼,,點(diǎn)這里。
創(chuàng)建一個(gè)Spring Boot項(xiàng)目來(lái) 試試~
引入example-spring-boot-starter
依賴
<dependency>
<groupId>com.example</groupId>
<artifactId>example-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
創(chuàng)建application.properties
,進(jìn)行配置
example.service.enabled=true
example.service.prefix=####
example.service.suffix=@@@@
創(chuàng)建一個(gè)簡(jiǎn)單的Spring Web Application,,注入Starter提供的ExampleService
看它能否正常工作~
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private ExampleService exampleService;
@GetMapping('/input')
public String input(String word){
return exampleService.wrap(word);
}
}
啟動(dòng)Application,,訪問(wèn)/input
接口試試看~
“
總結(jié)下Starter
的工作原理
Spring Boot
在啟動(dòng)時(shí)掃描項(xiàng)目所依賴的JAR包,尋找包含spring.factories
文件的JAR包- 根據(jù)
spring.factories
配置加載AutoConfigure
類 - 根據(jù)
@Conditional
注解的條件,,進(jìn)行自動(dòng)配置并將Bean
注入Spring Context