本文翻譯自:http://docs.spring.io/spring-boot/docs/2.0.0.M2/reference/htmlsingle/
詳細介紹Spring boot的關鍵特征,針對有一定springboot基礎的同學。
目錄
- 1 外部配置
- 1.1 配置隨機值
- 1.2 訪問命令行屬性
- 1.3 應用程式屬性檔案
- 1.4 配置文件特定的屬性
- 1.5 properties中的占位符
- 1.6 使用YAML而不是properties
- 1.6.1 加載YAML
- 1.6.2 將YAML作為Spring環境中的屬性
- 1.6.3 多個YAML文件
- 1.6.4 YAML的缺點
- 1.6.5 合并YAML列表
1. 外部配置
Spring Boot允許您外部化配置,以便在不同的環境中使用相同的應用程序代碼。您可以使用屬性文件,YAML文件,環境變量和命令行參數來外部化配置。可以使用@Value注釋將屬性值直接注入到您的bean中,通過Spring的Environment抽象訪問或通過@ConfigurationProperties綁定到結構化對象。
Spring Boot使用非常特殊的PropertySource命令,旨在允許明智地覆蓋值。屬性按以下順序考慮:
- Devtools全局設置屬性在您的主目錄(~/.spring-boot-devtools.properties當devtools是活動的)。
- @TestPropertySource注釋在你的單元測試中。
- @SpringBootTest #properties 注解屬性在你的單元測試中。
- 命令行參數。
- 來自SPRING_APPLICATION_JSON的屬性(嵌入在環境變量或系統屬性中的內嵌JSON)
- *ServletConfig *init參數。
- *ServletContext *init參數。
- 來自java的JNDI屬性:java:comp/env。
- Java系統屬性(System.getProperties())。
- OS環境變量。
- 一個RandomValuePropertySource,只有隨機的屬性。
- 特定于應用程序的應用程序屬性在打包的jar之外(application- {profile} .properties和YAML變量)。
- 封裝在jar中的配置文件特定的應用程序屬性(application- {profile} .properties和YAML變量)。
- 您的打包的jar(application.properties和YAML變量)之外的應用程序屬性。
- 應用程序屬性打包在你的jar中 (application.properties和YAML變量)。
- @PropertySource注釋在您的@Configuration類。
- 默認屬性(使用SpringApplication.setDefaultProperties指定)。
要提供一個具體的例子,假設你開發一個使用name屬性的@Component:
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
@Value("${name}")
private String name;
// ...
}
在您的應用程序類路徑(例如,您的jar中)中,您可以擁有一個application.properties,它為name提供了明智的默認屬性值。在新的環境中運行時,可以在您的jar之外提供一個application.properties來覆蓋該name;對于一次性測試,您可以使用特定的命令行開關啟動(例如,java -jar app.jar --name =“Spring”)。
注意:
SPRING_APPLICATION_JSON屬性可以在命令行中提供一個環境變量。例如在UN * X shell中:
$ SPRING_APPLICATION_JSON ='{“foo”:{“bar”:“spam”}}'java -jar myapp.jar
在這個例子中,你將在springEnvironment中以foo.bar=spam結尾。您還可以在系統變量中將JSON作為spring.application.json提供:
$ java -Dspring.application.json ='{“foo”:“bar”}'-jar myapp.jar
或命令行參數:
$ java - jar myapp.jar --spring.application.json ='{“foo”:“bar”}'
或作為JNDI變量java:comp / env / spring.application.json。
1.1 配置隨機值
RandomValuePropertySource可用于注入隨機值(例如,進入秘密或測試用例)。它可以產生整數,長整數,uuid或字符串,例如:
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
random.int* 語法是*OPEN value (,max) CLOSE
*,其中OPEN,CLOSE是任何字符和值,max是整數。如果提供max,則值為最小值,max為最大值(僅包含)。
1.2 訪問命令行屬性
默認情況下,SpringApplication將任何命令行選項參數(以' - '開頭,例如--server.port = 9000)轉換為property,并將其添加到Spring的Environment中。
如上所述,命令行屬性始終優先于其他屬性源。如果不希望將命令行屬性添加到Environment中,可以使用SpringApplication.setAddCommandLineProperties(false)禁用它們。
1.3 應用程式屬性檔案
SpringApplication將從以下位置的application.properties文件中加載屬性,并將它們添加到當前目錄的Spring Environment:
- 一個/ config子目錄中。
- 當前目錄
- 一個 classpath /config 保中
- 類路徑根
列表按優先級排序(在列表中定義的屬性中定義的屬性將覆蓋在較低位置中定義的位置)。
注意:您也可以使用YAML('.yml')文件替代“.properties”。
如果您不喜歡application.properties作為配置文件名,可以通過指定一個spring.config.name環境屬性來切換到另一個。您還可以使用spring.config.location環境屬性(目錄位置的逗號分隔列表或文件路徑)引用顯式位置。
$ java -jar myproject.jar --spring.config.name = myproject
或
$ java -jar myproject.jar --spring.config.location = classpath:/default.properties,classpath:/override.properties
注意:spring.config.name和spring.config.location非常早地用于確定哪些文件必須被加載,因此必須將其定義為環境屬性(通常是OS env,system屬性或命令行參數)。
如果spring.config.location包含目錄(而不是文件),它們應該以/結束(并將在加載之前附加從spring.config.name生成的名稱,包括特定于文件的文件名)。在spring.config.location中指定的文件按原樣使用,沒有支持特定于配置文件的變量,并且將被任何特定于配置文件的屬性覆蓋。
默認的搜索路徑classpath:,classpath:/ config,file:,file:config /始終被使用,不管spring.config.location的值如何。 此搜索路徑從最低優先級排序(file:config / 最高優先級)。
如果您指定自己的位置,則它們優先于所有默認位置,并使用相同的最低到最高優先級排序。 這樣,您可以在application.properties(或使用spring.config.name選擇的其他基礎名稱)中為應用程序設置默認值,并在運行時使用不同的文件覆蓋它,并保留默認值。
注意:如果使用環境變量而不是系統屬性,則大多數操作系統不允許使用周期分隔的鍵名稱,但可以使用下劃線(例如SPRING_CONFIG_NAME,而不是spring.config.name)。
注意:如果你在一個容器中運行JNDI屬性(在java:comp / env)或者servlet 可以使用上下文初始化參數來代替環境變量或系統屬性。
1.4 配置文件特定的屬性
除了application.properties文件之外,還可以使用命名約定application- {profile} .properties定義特定于配置文件的屬性。Environment具有默認配置文件(默認為[default]),如果沒有設置活動配置文件(即,如果沒有顯式激活配置文件,則加載了來自application-default.properties的屬性)。
配置文件特定的屬性從與標準application.properties相同的位置加載,配置文件特定的文件始終覆蓋非特定的文件,而不管特定于配置文件的文件是否在打包的jar內部或外部。
如果指定了幾個配置文件,則應用最后一個優先策略。例如,由spring.profiles.active屬性指定的配置文件通過SpringApplication API配置后添加,因此優先。
注意:如果您在spring.config.location中指定了任何文件,則不會考慮這些文件的特定于配置文件的變量。使用 如果還要使用特定于配置文件的屬性,請在spring.config.location中指定目錄。
1.5 properties中的占位符
application.properties中的值通過使用現有Environment進行過濾,以便您可以參考以前定義的值(例如,從系統屬性)。
app.name = MyApp
app.description = $ {app.name} is a Spring Boot application
您還可以使用此技術創建現有Spring Boot屬性的“簡短”變體。
1.6 使用YAML而不是properties
YAML是JSON的超集,因此這是一種用于指定分層配置數據的非常方便的格式。只要您的類路徑中有SnakeYAML庫,SpringApplication類將自動支持YAML作為屬性的替代方法。
注意:如果您使用“Starters”,SnakeYAML將通過spring-boot-starter自動提供。
1.6.1 加載YAML
Spring Framework提供了兩個可用于加載YAML文檔的方便類。 YamlPropertiesFactoryBean將加載YAML作為Properties,并且YamlMapFactoryBean將加載YAML作為Map。例如,以下YAML文檔:
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
將被轉換成這些屬性:
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML列表表示為具有[index]取消引用的屬性鍵,例如YAML:
my:
servers:
- dev.bar.com
- foo.bar.com
將被轉換成這些屬性:
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
要使用Spring DataBinder實用程序(這是@ConfigurationProperties所做的)綁定到這樣的屬性,您需要在類型為java.util.List(或Set)的目標bean中具有一個屬性,并且您需要提供一個setter,或者用可變值初始化它,例如這將綁定到上面的屬性
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
注意:
配置列表時,需要特別小心,因為覆蓋方式將無法正常工作。在上面的例子中,當我的幾個地方重新定義my.servers時,單個元素的目標是覆蓋,而不是列表。要確保具有較高優先級的PropertySource可以覆蓋列表,您需要將其定義為單個屬性:
my:
servers: dev.bar.com,foo.bar.com
1.6.2 將YAML作為Spring環境中的屬性
可以使用YamlPropertySourceLoader類在SpringEnvironment中將YAML作為PropertySource進行公開。這允許您使用熟悉的@Value注釋和占位符語法來訪問YAML屬性。
1.6.3 多個YAML文件
您可以使用spring.profiles鍵指定單個文件中的多個配置文件特定的YAML文檔,以指示文檔何時應用。例如:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
在上面的示例中,如果development配置文件處于活動狀態,則server.address屬性將為127.0.0.1。如果development和production配置文件未啟用,則該屬性的值將為192.168.1.100。
如果應用程序上下文啟動時沒有顯式激活,默認配置文件將被激活。所以在這個YAML中,我們為security.user.password設置一個僅在“默認”配置文件中可用的值:
server:
port: 8000
---
spring:
profiles: default
security:
user:
password: weak
而在此示例中,由于密碼未附加到任何配置文件,因此始終設置密碼,必要時必須在所有其他配置文件中顯式重置密碼:
server:
port: 8000
security:
user:
password: weak
使用“spring.profiles”元素指定的彈簧輪廓可以選擇使用!字符。如果為單個文檔指定了否定和非否定的配置文件,則至少有一個非否定配置文件必須匹配,沒有否定配置文件可能匹配。
1.6.4 YAML的缺點
不能通過@PropertySource注釋來加載YAML文件。因此,在需要以這種方式加載值的情況下,需要使用屬性文件。
1.6.5 合并YAML列表
如上所述,任何YAML內容最終都轉化為屬性。當通過配置文件覆蓋“列表”屬性時,該過程可能是直觀的。
例如,假設默認情況下,name和description屬性為null的MyPojo對象。讓我們從FooProperties中公開MyPojo的列表:
@ConfigurationProperties("foo")
public class FooProperties {
private final List<MyPojo> list = new ArrayList<>();
public List<MyPojo> getList() {
return this.list;
}
}
請考慮以下配置:
foo:
list:
- name: my name
description: my description
---
spring:
profiles: dev
foo:
list:
- name: my another name
如果dev配置文件不活動,FooProperties.list將包含一個如上定義的MyPojo條目。如果啟用了dev配置文件,list仍將只包含一個條目(名稱為“我的另一個名稱”,描述為null)。此配置不會將第二個MyPojo實例添加到列表中,它不會合并項。
foo:
list:
- name: my name
description: my description
- name: another name
description: another description
---
spring:
profiles: dev
foo:
list:
- name: my another name
在上面的示例中,考慮到dev配置文件處于活動狀態,FooProperties.list將包含一個MyPojo實體(包含名稱為“my another 描述為null)。
當在多個配置文件中指定集合時,將使用具有最高優先級的集合(并且僅使用該集合):