spring-boot-starter
在前面我們創(chuàng)建工程的時候呵曹,選擇了依賴Web
,我們打開pom.xml
肌括,將看到
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
- 這里的dependency里面沒有
version
標簽诅福,這是為什么呢?因為我們繼承了spring-boot-starter-parent
需忿,該包中加入了大部分我們需要的依賴包及其版本號诅炉,根據(jù)mvn的依賴繼承原理,我們這里就不需要再寫版本號了屋厘。 - 我們的第一個依賴
spring-boot-starter-web
涕烧,它包含了編寫一個web站點需要的東西,比如我們要使用的注解:@SpringBootApplication
,@RestController
,@RequestMapping
,@ResponseBody
汗洒,等等议纯。
我們之后會經(jīng)常使用別人寫好的starter
,必要的時候也需要自己寫溢谤。為了弄清楚其中的原委痹扇,我們接下來寫一個試試。
重構(gòu)項目結(jié)構(gòu)
1. 添加目錄learn-app
溯香,將src
目錄移動到learn-app
下鲫构,修改頂層pom.xml
。
...
<packaging>pom</packaging>
...
<modules>
<module>learn-app</module>
</modules>
...
- 修改
packaging
為pom玫坛。 - 添加
modules
標簽结笨,將learn-app
模塊引進來。
這一步不是必需的湿镀,只是為了方便我們以后的開發(fā)炕吸,也順便演示一下項目結(jié)構(gòu)的重構(gòu)技巧。
2. 在learn-app下添加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>
<artifactId>learn-app</artifactId>
<packaging>jar</packaging>
<name>learn-app</name>
<description>spring-boot-learn-app</description>
<parent>
<groupId>me.readyou</groupId>
<artifactId>spring-boot-learn</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
這里主要修改了parent標簽。
3. 在Maven Projects
窗口的learn-app
下重新創(chuàng)建Debug Configuration
(見工程初始化)
創(chuàng)建包string-handler-spring-boot-starter
通常寫一個starter需要包含以下幾個部分:
主服務類:將來會通過
Autowired
使用的類。屬性配置類:用來從配置文件或配置服務器獲取配置步氏。
自動配置類:根據(jù)配置的屬性患民,生成主服務類的對象考余,注入到系統(tǒng)中。
將自動配置類添加到
resources/META-INF/spring.factories
文件中,沒有這一步的話,上面一步不生效斩祭,即通過本配置,才能讓系統(tǒng)找到相應的自動配置類乡话,并進行依賴注入摧玫。-
新建目錄與文件
├── pom.xml ├── src │ └── main │ ├── java │ │ └── me │ │ └── readyou │ │ └── springbootlearn │ │ └── starter │ │ └── stringhandler │ │ ├── StringHandlerAutoConfiguration.java │ │ ├── StringHandlerProperties.java │ │ └── StringHandlerService.java │ └── resources │ └── META-INF │ └── spring.factories
-
編輯
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>me.readyou</groupId> <artifactId>string-handler-spring-boot-starter</artifactId> <packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version> <name>string-handler-spring-boot-starter</name> <description>starter to log execute time of controller</description> <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>
-
編輯
StringHandlerService.java
:package me.readyou.springbootlearn.starter.stringhandler; /** * Created by wuxinlong on 18/5/2. */ // 這是我們要提供的Service,但這里并不需要@service的注解 // 因為我們在自動配置類中绑青,會直接調(diào)用構(gòu)造函數(shù)生成對象 public class StringHandlerService { private int handleType; public StringHandlerService(int handleType) { this.handleType = handleType; } public String doHandle(String str) { if (str == null) { return null; } switch (handleType) { case 1: return str.toLowerCase(); case 2: return str.toUpperCase(); default: return str.toUpperCase(); } } }
-
編輯
StringHandlerProperties.java
:package me.readyou.springbootlearn.starter.stringhandler; import org.springframework.boot.context.properties.ConfigurationProperties; /** * Created by wuxinlong on 18/5/2. */ @ConfigurationProperties("spring.boot.learn.string.handler") public class StringHandlerProperties { private int handleType; public int getHandleType() { return handleType; } public StringHandlerProperties setHandleType(int handleType) { this.handleType = handleType; return this; } }
-
編輯
StringHandlerAutoConfiguration.java
诬像,通過Autowired
使用StringHandlerProperties
獲取屬性屋群,并利用屬性生成真正的Service對象:package me.readyou.springbootlearn.starter.stringhandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by wuxinlong on 18/5/2. */ @Configuration @ConditionalOnClass(StringHandlerService.class) @EnableConfigurationProperties(StringHandlerProperties.class) public class StringHandlerAutoConfiguration { @Autowired private StringHandlerProperties stringHandlerProperties; @Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.boot.learn.string.handler", value = "enabled", havingValue = "true") StringHandlerService exampleService() { return new StringHandlerService(stringHandlerProperties.getHandleType()); } }
解釋一下這里的幾個注解:
@Bean
表示生成一個新的Bean;@ConditionalOnMissingBean
表示沒有該類時才配置坏挠,防止重復配置谓晌;@ConditionalOnProperty
只有屬性滿足某些條件時才生效。 -
編輯
spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ me.readyou.springbootlearn.starter.stringhandler.StringHandlerAutoConfiguration
執(zhí)行命令
mvn install
安裝包到本地倉庫癞揉。
使用starter包
-
添加依賴
<!-- spring-boot-learn/pom.xml --> ... <dependency> <groupId>me.readyou</groupId> <artifactId>string-handler-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </dependencyManagement> ...
<!-- spring-boot-learn/learn-app/pom.xml --> ... <dependency> <groupId>me.readyou</groupId> <artifactId>string-handler-spring-boot-starter</artifactId> </dependency> </dependencies> ...
-
修改
spring-boot-learn/learn-app/src/main/resources/application.properties
,添加配置:spring.boot.learn.string.handler.enabled=true spring.boot.learn.string.handler.handleType=2
在controller類中使用
// ...
public class HelloController {
@Autowired
private StringHandlerService stringHandlerService;
@RequestMapping("/")
@ResponseBody
String home() {
String msg = "Hello World!";
return stringHandlerService.doHandle(msg);
}
}
效果
- 重啟服務溺欧,瀏覽器中可以看到全小寫的
hello world!
喊熟。 - 修改配置項:
spring.boot.learn.string.handler.handleType=2
,重啟服務姐刁,瀏覽器中可以看到全大寫的HELLO WORLD!
芥牌。
原文鏈接
https://github.com/readyou/spring-boot-learn/blob/master/docs/01_project-init.md