springboot--自定義starter
轉載:https://www.jianshu.com/p/45538b44e04e
眾所周知(不知道?點此),Spring Boot由眾多Starter組成,隨著版本的推移Starter家族成員也與日俱增。在傳統Maven專案中通常將一些層、元件拆分為模組來管理,以便相互依賴複用,在Spring Boot專案中我們則可以建立自定義Spring Boot Starter來達成該目的。
好,開始,先建立一個Maven專案並引入依賴,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 http://maven.apache.org/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>
這裡說下artifactId
的命名問題,Spring 官方 Starter通常命名為spring-boot-starter-{name}
如 spring-boot-starter-web
, Spring官方建議非官方Starter命名應遵循{name}-spring-boot-starter
的格式。
這裡講一下我們的Starter要實現的功能,很簡單,提供一個Service
,包含一個能夠將字串加上前後綴的方法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; } }
字首、字尾通過讀取application.properties(yml)
內的引數獲得
@ConfigurationProperties("example.service")
public class ExampleServiceProperties {
private String prefix;
private String suffix;
//省略 getter setter
重點,編寫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()); } }
解釋下用到的幾個和Starter相關的註解:
@ConditionalOnClass
,當classpath
下發現該類的情況下進行自動配置。@ConditionalOnMissingBean
,當Spring Context
中不存在該Bean
時。@ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true")
,當配置檔案中example.service.enabled=true
時。
更多相關注解,建議閱讀官方文件該部分。
最後一步,在resources/META-INF/
下建立spring.factories
檔案,內容供參考下面~
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autocinfigure.ExampleAutoConfigure
OK,完事,執行 mvn:install
打包安裝,一個Spring Boot Starter便開發完成了。如果你需要該Starter的原始碼,點這裡。
建立一個Spring Boot專案來 試試~
引入example-spring-boot-starter
依賴
<dependency>
<groupId>com.example</groupId>
<artifactId>example-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
建立application.properties
,進行配置
example.service.enabled=true
example.service.prefix=####
[email protected]@@@
建立一個簡單的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);
}
}
啟動Application,訪問/input
介面試試看~
總結下Starter
的工作原理
Spring Boot
在啟動時掃描專案所依賴的JAR包,尋找包含spring.factories
檔案的JAR包- 根據
spring.factories
配置載入AutoConfigure
類 - 根據
@Conditional
註解的條件,進行自動配置並將Bean
注入Spring Context