属性和配置
本节介绍有关设置和读取属性以及配置设置及其与 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 目标或自定义插件的配置。有关更多详细信息,请参阅 插件使用页面。
|
如果您没有使用启动器父级,则需要在 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 过滤,您可能还需要更改默认过滤器令牌以使用 其他分隔符。
|
在这种特定情况下,端口绑定在 Heroku 或 Cloud Foundry 等 PaaS 环境中有效。在这两个平台中,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 配置文件
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
中设置活动配置文件,如以下示例所示
-
属性
-
YAML
spring.profiles.active=production
spring:
profiles:
active: "production"
以这种方式设置的值将被系统属性或环境变量设置替换,但不会被 SpringApplicationBuilder.profiles()
方法替换。因此,后者的 Java API 可用于增强配置文件,而无需更改默认值。
有关更多信息,请参阅“Spring Boot 特性”部分中的“配置文件”。
设置默认配置文件名称
默认配置文件是在没有活动配置文件的情况下启用的配置文件。默认情况下,默认配置文件的名称为default
,但可以使用系统属性(spring.profiles.default
)或操作系统环境变量(SPRING_PROFILES_DEFAULT
)更改。
在 Spring Boot 中,您也可以在application.properties
中设置默认配置文件名称,如下例所示
-
属性
-
YAML
spring.profiles.default=dev
spring:
profiles:
default: "dev"
有关更多信息,请参阅“Spring Boot 特性”部分中的“配置文件”。
根据环境更改配置
Spring Boot 支持多文档 YAML 和属性文件(有关详细信息,请参阅使用多文档文件),这些文件可以根据活动配置文件有条件地激活。
如果文档包含spring.config.activate.on-profile
键,则配置文件值(逗号分隔的配置文件列表或配置文件表达式)将被馈送到 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
来获得。有关加载属性的确切顺序的更多信息,请参阅 "外部化配置"。