文章已經收錄在 Github.com/niumoo/JavaNotes ,更有 Java 程序員所須要掌握的核心知識,歡迎Star和指教。
歡迎關注個人 公衆號,文章每週更新。
注意:本 Spring Boot 系列文章基於 Spring Boot 版本 v2.1.1.RELEASE 進行學習分析,版本不一樣可能會有細微差異。
不論是經過官方提供的方式獲取 Spring Boot 項目,仍是經過 IDEA 快速的建立 Spring Boot 項目,咱們都會發如今 resource 有一個配置文件 application.properties
,也有多是application.yml
.這個文件也就是 Spring Boot 的配置文件。html
<!-- more -->java
在 Spring Boot
中,官方推薦使用 properties
或者 YAML
文件來完成配置,對於 YAML
文件格式還不瞭解的能夠查看官方的具體格式,這裏只作簡單介紹。 git
YAML 語法規則:程序員
#
開頭的行表示註釋YAML 支持的數據結構:github
1.單純的變量,不可再分的單個的值,如數字,字符串等。golang
name: Darcy age: 12 # ~表示NULL值 email: ~ # 多行字符串可使用|保留換行符,也可使用>摺疊換行。 # +表示保留文字塊末尾的換行,-表示刪除字符串末尾的換行。 message:|- Hello world
2.數組,一組按次序排列的值。web
lang: - java - golang - c 或者行內寫法 lang:[java,golang,c]
3.對象,鍵值對的集合。面試
person: name:Darcy age:20 或者行內寫法 person:{name:Darcy,age:20}
使用 YAML
支持的三種數據結構經過組合能夠造成複雜的複合結構。spring
# 服務啓動端口號 server: port: 8080 # 配置person屬性值 person: last-name: Darcy age: 20 birth: 2018/01/01 email: gmail@gmail.com maps: key1:java key2:golang lists: - a - b - c dog: name: 旺財 age: 2
須要注意的是 YAML
文件不能使用@PropertySource
加載shell
properties
配置文件簡單好用,在各類配置環境裏均可以看到它的身影,它簡單易用,可是在配置複雜結構時不如 YAML
優雅美觀。一樣拿上面的 YAML
的複合結構舉例,演示一樣的配置在 properties
文件中的寫法。
# 服務啓動端口號 server.port=8080 # 配置屬性值(使用IDE進行配置須要處理編碼問題,否則中文會發送亂碼現象) person.last-name=張三 person.age=18 person.birth=2018/12/06 person.email=niu@gmail.com person.maps.key1=c person.maps.key2=java person.maps.key3=golang person.lists=a,b,c,d person.dog.name=旺財 person.dog.age=1
RandomValuePropertySource
類對於注入隨機值頗有用(例如,注入祕密或測試用例)。它能夠生成整數,長整數,uuid 或字符串等,經過 Spring Boot 對咱們的封裝,咱們能夠輕鬆的使用。
佔位符容許在配置的值中引用以前定義過的變量。
# 生成隨機值 bootapp.secret=$ {random.value} bootapp.number=$ {random.int} bootapp.bignumber=$ {random.long} bootapp.uuid=$ {random.uuid} bootapp.number.less.than.ten=$ {random.int(10)} bootapp.number.in.range=$ {random.int [1024,65536]} # 屬性的佔位符 bootapp.name=SpringBoot bootapp.description=${bootapp.name}是一個spring應用程序
經過上面的介紹,能夠發現不論是使用 YAML
仍是 Properties
均可以進行配置文件的編寫,可是還不知道具體的使用方式,經過下面的幾個註解,可讓咱們瞭解到這些配置的具體使用方式。
在使用配置以前,添加所需依賴。
<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> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- 導入配置文件處理器,在配置相關文件時候會有提示 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
@ConfigurationProperties
註解是 Spring Boot
提供的一種使用屬性的注入方法。不只能夠方便的把配置文件中的屬性值與所註解類綁定,還支持鬆散綁定,JSR-303 數據校驗等功能。以上面演示的 Properties
的配置爲例演示 @ConfigurationProperties
註解的使用。
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import javax.validation.constraints.Email; import java.util.Date; import java.util.List; import java.util.Map; /** * <p> * @Author niujinpeng * @Date 2018/12/6 22:54 */ @Data @Component @ConfigurationProperties(prefix = "person") @Validated public class Person { private String lastName; private Integer age; private Date birth; private Map<String, String> maps; private List<String> lists; private Dog dog; /** * 支持數據校驗 */ @Email private String email; }
@Data
是 Lombok 的註解,會爲這個類全部屬性添加 getting 和 setting 方法,此外還提供了equals、canEqual、hashCode、toString 方法。@Component
自動添加 bean 到 spring 容器中。@ConfigurationProperties
告訴這個類的屬性都是配置文件裏的屬性,prefix 指定讀取配置文件的前綴。@Value
支持直接從配置文件中讀取值,同時支持 SpEL 表達式,可是不支持複雜數據類型和數據驗證,下面是具體的使用。
import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import javax.validation.constraints.Email; import java.util.Date; import java.util.List; import java.util.Map; @Data @Component @Validated public class PersonValue { /** * 直接從配置文件讀取一個值 */ @Value("${person.last-name}") private String lastName; /** * 支持SpEL表達式 */ @Value("#{11*4/2}") private Integer age; @Value("${person.birth}") private Date birth; /** * 不支持複雜類型 */ private Map<String, String> maps; private List<String> lists; private Dog dog; /** * 不支持數據校驗 */ @Email @Value("xxx@@@@") private String email; }
編寫單元測試代碼測試代碼查看屬性綁定是否成功。
import net.codingme.boot.domain.Person; import net.codingme.boot.domain.PersonValue; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class HelloApplicationTests { @Autowired private MockMvc mvc; @Autowired private Person person; @Autowired private PersonValue personValue; /** * 模擬請求測試 * * @throws Exception */ @Test public void testGetHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string("Greetings from Spring Boot!")); } /** * 測試@ConfigurationProperties */ @Test public void testPersion() { System.out.println(person); } /** * 測試@Value 引入配置值 */ @Test public void testPersionValue() { System.out.println(personValue); } }
運行發現數據已經正常綁定。
經過上面的示例,也能夠發現 @ConfigurationProperties
和 @Value
的區別。
特徵 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量注入配置文件屬性 | 一個一個注入 |
鬆散綁定(鬆散的語法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR-303 數據校驗 | 支持 | 不支持 |
複雜類型 | 支持 | 不支持 |
@ConfigurationProperties
和 @Value
的使用場景。
若是說,只是在某個業務邏輯中獲取配置文件的某個值,使用 @Value
.
若是說,專門編寫有一個 Java Bean 來和配置文件映射,使用 @ConfigurationProperties
.
隨着業務複雜性的增長,配置文件也愈來愈多,咱們會以爲全部的配置都寫在一個 properties 文件會使配置顯得繁雜不利於管理,所以但願能夠把映射屬性類的配置單獨的抽取出來。因爲 Spring Boot 默認讀取 application.properties
,所以在抽取以後以前單獨的@ConfigurationProperties(prefix = "person")
已經沒法讀取到信息。這是可使用 @PropertySource
註解來指定要讀取的配置文件。
須要注意的是,使用 @PropertySource
加載自定義的配置文件,,因爲 @PropertySource
指定的文件會優先加載,因此若是在 applocation.properties
中存在相同的屬性配置,會覆蓋前者中對於的值。
若是抽取 person
配置爲單獨文件domain-person.properties
。
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import javax.validation.constraints.Email; import java.util.Date; import java.util.List; import java.util.Map; /** * <p> * @Author niujinpeng * @Date 2018/12/6 22:54 */ @Data @Component @Validated @PropertySource(value = "classpath:domain-person.properties") @ConfigurationProperties(value = "person") public class PersonSource { private String lastName; private Integer age; private Date birth; private Map<String, String> maps; private List<String> lists; private Dog dog; /** * 支持數據校驗 */ @Email private String email; }
在主配置文件編寫的時候,文件名能夠是 application-{name}.properties
.默認使用的是application.properties
.
那麼如何在配置文件中激活其餘的配置文件呢?只須要在 application.properties
啓用其餘文件。
# 激活 application-prod.properties文件 spring.profiles.active=prod
若是是使用 YAML 配置文件,咱們可使用文件塊的形式,在一個 YAML 文件就能夠達到多文件配置的效果,下面是 Spring Boot 使用 YAML 文件進行多環境配置的方式。
server: port: 8083 profiles: active: dev # 指定環境爲dev # 使用三個---進行文檔塊區分 --- server: port: 8084 spring: profiles: dev --- server: port: 8085 spring: profiles: prod
除了以上的兩種配置文件激活方式以外,還有另外兩種種激活方式。
--spring.profiles.active=prod
-Dspring.profiles.active=prod
若是須要激活其餘的配置文件,可使用 spring.config.location=G:/application.properties
進行配置。
配置文件默認會從四個地方加載,且優先級從高到低。優先級高的配置會覆蓋優先級低的配置。若是多個位置的配置同時存在,不一樣的配置信息會造成互補配置。
-file: ./config/ -file: ./ -classpath: /config/ -classpath: /
Spring Boot 的外部配置文件加載的方式有不少,具體能夠參考官方文檔。這些配置加載優先級從高到底,優先級高的配置會覆蓋優先級低的配置。
下面介紹幾種常見的加載配置的順序。
命令行參數運行,全部的配置均可以在命令行上執行,多個配置空格隔開。
java -jar springboot-0.0.1-SNAPSHOT.jar --server.port=9999 --sercer.context-path=/spring
文章代碼已經上傳到 GitHub Spring Boot 配置文件。
最後的話
文章每週持續更新,本文 Github.com/niumoo/JavaNotes 已收錄。更有一線大廠面試點,Java程序員所須要掌握的核心知識等文章,也整理了不少個人文字,歡迎 Star 和完善,但願咱們一塊兒變得優秀。
文章有幫助能夠點「贊」在看或 Star,我都喜歡,謝謝你!
要實時關注我更新的文章以及分享的乾貨,能夠關注「 未讀代碼 」公衆號,公衆號回覆 666 能夠領取不少資料。