屬性和配置
本節包含關於設定和讀取屬性和組態設定以及它們與 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://127.0.0.1/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://127.0.0.1/test
server.port=9000
有關 YAML 的更多資訊,請參閱 "`Spring Boot 功能'" 章節中的使用 YAML。
設定啟用的 Spring Profile
Spring Environment
具有用於此目的的 API,但您通常會設定系統屬性 (spring.profiles.active
) 或作業系統環境變數 (SPRING_PROFILES_ACTIVE
)。此外,您可以使用 -D
引數啟動您的應用程式(請記住將其放在主類別或 jar 歸檔之前),如下所示
$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
在 Spring Boot 中,您也可以在 application.properties
中設定啟用的 profile,如下例所示
-
屬性
-
YAML
spring.profiles.active=production
spring:
profiles:
active: "production"
以此方式設定的值會被系統屬性或環境變數設定取代,但不會被 SpringApplicationBuilder.profiles()
方法取代。因此,後者的 Java API 可用於擴充 profile,而無需變更預設值。
有關更多資訊,請參閱“Spring Boot 功能”章節中的Profile。
設定預設 Profile 名稱
預設 profile 是在沒有啟用任何 profile 時啟用的 profile。預設情況下,預設 profile 的名稱為 default
,但可以使用系統屬性 (spring.profiles.default
) 或作業系統環境變數 (SPRING_PROFILES_DEFAULT
) 變更它。
在 Spring Boot 中,您也可以在 application.properties
中設定預設 profile 名稱,如下例所示
-
屬性
-
YAML
spring.profiles.default=dev
spring:
profiles:
default: "dev"
有關更多資訊,請參閱“Spring Boot 功能”章節中的Profile。
根據環境變更組態
Spring Boot 支援多文件 YAML 和 Properties 檔案(有關詳細資訊,請參閱使用多文件檔案),這些檔案可以根據啟用的 profile 有條件地啟用。
如果文件包含 spring.config.activate.on-profile
鍵,則 profile 值(以逗號分隔的 profile 清單或 profile 表達式)會饋送到 Spring Environment.acceptsProfiles()
方法中。如果 profile 表達式符合,則該文件會包含在最終合併中(否則,則不會),如下例所示
-
屬性
-
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 profile 處於啟用狀態,則端口為 9001。如果 ‘production’ 處於啟用狀態,則端口為 0。
文件會按照它們遇到的順序合併。後面的值會覆蓋較早的值。 |
探索外部屬性的內建選項
Spring Boot 將來自 application.properties
(或 YAML 檔案和其他位置)的外部屬性綁定到執行時的應用程式中。在單個位置沒有(並且技術上不可能有)所有支援屬性的詳盡清單,因為貢獻可能來自類別路徑上的其他 jar 檔案。
具有 Actuator 功能的執行中應用程式具有 configprops
端點,該端點顯示透過 @ConfigurationProperties
可用的所有綁定和可綁定屬性。
附錄包含一個application.properties
範例,其中列出了 Spring Boot 支援的最常見屬性。明確的清單來自搜尋原始程式碼中的 @ConfigurationProperties
和 @Value
註解以及偶爾使用 Binder
。有關載入屬性的確切順序的更多資訊,請參閱外部化組態。