屬性和配置
本節包含有關設定和讀取屬性及配置設定及其與 Spring Boot 應用程式互動的主題。
在構建時自動展開屬性
您可以使用現有的構建配置來自動展開屬性,而不是對一些也指定在專案構建配置中的屬性進行硬編碼。這在 Maven 和 Gradle 中都可能實現。
使用 Maven 自動展開屬性
您可以使用資源過濾來自動展開 Maven 專案中的屬性。如果您使用 spring-boot-starter-parent,則可以使用 @..@ 佔位符引用您的 Maven “專案屬性”,如以下示例所示:
-
屬性
-
YAML
app:
encoding: "@project.build.sourceEncoding@"
java:
version: "@java.version@"
只有生產配置會以這種方式進行過濾(換句話說,不對 src/test/resources 應用過濾)。 |
如果您啟用 addResources 標誌,spring-boot:run 目標可以將 src/main/resources 直接新增到類路徑(用於熱過載)。這樣做會規避資源過濾和此功能。您可以改用 exec:java 目標或自定義外掛的配置。有關更多詳細資訊,請參閱外掛使用頁面。 |
如果您不使用 starter parent,則需要在 pom.xml 的 <build/> 元素內包含以下元素:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
您還需要在 <plugins/> 中包含以下元素:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>@</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
如果您在配置中使用標準 Spring 佔位符(例如 ${placeholder}),則 useDefaultDelimiters 屬性很重要。如果未將該屬性設定為 false,則這些佔位符可能會在構建時展開。 |
使用 Gradle 自動展開屬性
您可以透過配置 Java 外掛的 processResources 任務來自動展開 Gradle 專案中的屬性,如以下示例所示:
tasks.named('processResources') {
expand(project.properties)
}
然後,您可以使用佔位符引用您的 Gradle 專案的屬性,如以下示例所示:
-
屬性
-
YAML
app.name=${name}
app.description=${description}
app:
name: "${name}"
description: "${description}"
Gradle 的 expand 方法使用 Groovy 的 SimpleTemplateEngine,它轉換 ${..} 標記。${..} 樣式與 Spring 自己的屬性佔位符機制衝突。要將 Spring 屬性佔位符與自動展開一起使用,請按以下方式轉義 Spring 屬性佔位符:\${..}。 |
外部化 SpringApplication 的配置
一個 SpringApplication 具有 bean 屬性設定器,因此您可以在建立應用程式時使用其 Java API 來修改其行為。或者,您可以透過在 spring.main.* 中設定屬性來外部化配置。例如,在 application.properties 中,您可能具有以下設定:
-
屬性
-
YAML
spring.main.web-application-type=none
spring.main.banner-mode=off
spring:
main:
web-application-type: "none"
banner-mode: "off"
然後,Spring Boot 啟動時不會列印橫幅,並且應用程式不會啟動嵌入式 Web 伺服器。
外部配置中定義的屬性會覆蓋並替換透過 Java API 指定的值,但主源除外。主源是提供給 SpringApplication 建構函式的那些源:
-
Java
-
Kotlin
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
import org.springframework.boot.Banner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
object MyApplication {
@JvmStatic
fun main(args: Array<String>) {
val application = SpringApplication(MyApplication::class.java)
application.setBannerMode(Banner.Mode.OFF)
application.run(*args)
}
}
或提供給 SpringApplicationBuilder 的 sources(…) 方法:
-
Java
-
Kotlin
import org.springframework.boot.Banner;
import org.springframework.boot.builder.SpringApplicationBuilder;
public class MyApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF)
.sources(MyApplication.class)
.run(args);
}
}
import org.springframework.boot.Banner
import org.springframework.boot.builder.SpringApplicationBuilder
object MyApplication {
@JvmStatic
fun main(args: Array<String>) {
SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF)
.sources(MyApplication::class.java)
.run(*args)
}
}
鑑於以上示例,如果我們有以下配置:
-
屬性
-
YAML
spring.main.sources=com.example.MyDatabaseConfig,com.example.MyJmsConfig
spring.main.banner-mode=console
spring:
main:
sources: "com.example.MyDatabaseConfig,com.example.MyJmsConfig"
banner-mode: "console"
實際應用程式將顯示橫幅(被配置覆蓋)並使用三個源作為 ApplicationContext。應用程式源是:
-
MyApplication(來自程式碼) -
MyDatabaseConfig(來自外部配置) -
MyJmsConfig(來自外部配置)
更改應用程式外部屬性的位置
預設情況下,來自不同源的屬性以定義的順序新增到 Spring Environment 中(有關確切順序,請參閱“Spring Boot 功能”部分中的外部化配置)。
您還可以提供以下系統屬性(或環境變數)來改變行為:
-
spring.config.name(SPRING_CONFIG_NAME):預設為application作為檔名的根。 -
spring.config.location(SPRING_CONFIG_LOCATION):要載入的檔案(例如類路徑資源或 URL)。為本文件設定了一個單獨的Environment屬性源,並且它可以透過系統屬性、環境變數或命令列進行覆蓋。
無論您在環境中設定了什麼,Spring Boot 始終按上述方式載入 application.properties。預設情況下,如果使用 YAML,則帶有“.yaml”和“.yml”副檔名的檔案也會新增到列表中。
如果您想了解有關正在載入的檔案的詳細資訊,可以將 org.springframework.boot.context.config 的日誌級別設定為 trace。 |
使用“簡短”命令列引數
有些人喜歡使用(例如)--port=9000 而不是 --server.port=9000 來在命令列上設定配置屬性。您可以透過在 application.properties 中使用佔位符來啟用此行為,如以下示例所示:
-
屬性
-
YAML
server.port=${port:8080}
server:
port: "${port:8080}"
如果您繼承自 spring-boot-starter-parent POM,則 maven-resources-plugins 的預設過濾器令牌已從 ${*} 更改為 @ (即 @maven.token@ 而不是 ${maven.token}),以防止與 Spring 風格的佔位符發生衝突。如果您直接為 application.properties 啟用了 Maven 過濾,您可能還希望將預設過濾器令牌更改為使用其他分隔符。 |
在這種特定情況下,埠繫結在 PaaS 環境(如 Heroku 或 Cloud Foundry)中有效。在這兩個平臺上,PORT 環境變數會自動設定,Spring 可以繫結到 Environment 屬性的大寫同義詞。 |
將 YAML 用於外部屬性
YAML 是 JSON 的一個超集,因此是一種方便的語法,用於以分層格式儲存外部屬性,如以下示例所示:
spring:
application:
name: "cruncher"
datasource:
driver-class-name: "com.mysql.jdbc.Driver"
url: "jdbc:mysql:///test"
server:
port: 9000
建立一個名為 application.yaml 的檔案並將其放在類路徑的根目錄中。然後將 snakeyaml 新增到您的依賴項中(Maven 座標 org.yaml:snakeyaml,如果您使用 spring-boot-starter,則已包含)。YAML 檔案被解析為 Java Map<String,Object>(像 JSON 物件),Spring Boot 會展平該對映,使其只有一層深並具有句點分隔的鍵,就像許多人習慣於使用 Java 中的 Properties 檔案一樣。
前面的 YAML 示例對應於以下 application.properties 檔案:
spring.application.name=cruncher
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///test
server.port=9000
有關 YAML 的更多資訊,請參閱“Spring Boot 功能”部分中的使用 YAML。
設定活動 Spring 配置檔案
Spring Environment 有一個用於此的 API,但您通常會設定一個系統屬性 (spring.profiles.active) 或一個 OS 環境變數 (SPRING_PROFILES_ACTIVE)。此外,您可以使用 -D 引數啟動應用程式(記住將其放在主類或 jar 檔案之前),如下所示:
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
在 Spring Boot 中,您還可以在 application.properties 中設定活動配置檔案,如以下示例所示:
-
屬性
-
YAML
spring.profiles.active=production
spring:
profiles:
active: "production"
以這種方式設定的值會被系統屬性或環境變數設定替換,但不會被 SpringApplicationBuilder.profiles() 方法替換。因此,後者的 Java API 可用於在不更改預設值的情況下增強配置檔案。
有關更多資訊,請參閱“Spring Boot 功能”部分中的配置檔案。
設定預設配置檔名
預設配置檔案是在沒有配置檔案啟用時啟用的配置檔案。預設情況下,預設配置檔案的名稱是 default,但可以使用系統屬性 (spring.profiles.default) 或 OS 環境變數 (SPRING_PROFILES_DEFAULT) 進行更改。
在 Spring Boot 中,您還可以在 application.properties 中設定預設配置檔名,如以下示例所示:
-
屬性
-
YAML
spring.profiles.default=dev
spring:
profiles:
default: "dev"
有關更多資訊,請參閱“Spring Boot 功能”部分中的配置檔案。
根據環境更改配置
Spring Boot 支援多文件 YAML 和 Properties 檔案(有關詳細資訊,請參閱使用多文件檔案),它們可以根據活動配置檔案有條件地啟用。
如果文件包含 spring.config.activate.on-profile 鍵,則 profiles 值(逗號分隔的配置檔案列表或配置檔案表示式)將饋送到 Spring Environment.acceptsProfiles() 方法中。如果配置檔案表示式匹配,則該文件將包含在最終合併中(否則不包含),如以下示例所示:
-
屬性
-
YAML
server.port=9000
#---
spring.config.activate.on-profile=development
server.port=9001
#---
spring.config.activate.on-profile=production
server.port=0
server:
port: 9000
---
spring:
config:
activate:
on-profile: "development"
server:
port: 9001
---
spring:
config:
activate:
on-profile: "production"
server:
port: 0
在前面的示例中,預設埠是 9000。但是,如果名為“development”的 Spring 配置檔案處於活動狀態,則埠為 9001。如果“production”處於活動狀態,則埠為 0。
| 文件按其遇到的順序合併。後來的值會覆蓋較早的值。 |
發現外部屬性的內建選項
Spring Boot 在執行時將 application.properties(或 YAML 檔案和其他位置)中的外部屬性繫結到應用程式中。在單個位置沒有(技術上也不能有)所有支援的屬性的詳盡列表,因為貢獻可能來自類路徑上的其他 jar 檔案。
具有 Actuator 功能的執行中的應用程式有一個 configprops 端點,該端點顯示透過 @ConfigurationProperties 可用的所有繫結和可繫結屬性。
附錄包含一個 application.properties 示例,其中列出了 Spring Boot 支援的最常見屬性。確切的列表來自搜尋 @ConfigurationProperties 和 @Value 註解以及偶爾使用 Binder 的原始碼。有關載入屬性的確切順序的更多資訊,請參閱外部化配置。