77. 属性和配置
本节包括有关设置和读取属性和配置设置以及它们与 Spring Boot 应用程序的交互的主题。
77.1 在构建时自动扩展属性
您可以使用现有的构建配置自动扩展它们,而不是对项目的构建配置中也指定的某些属性进行硬编码。在 Maven 和 Gradle 中都是可能的。
77.1.1 使用 Maven 自动扩展属性
您可以使用资源过滤从 Maven 项目自动扩展属性。如果使用spring-boot-starter-parent
,则可以使用@[email protected]
占位符来引用 Maven 的“项目属性”,如以下示例所示:
app.encoding[emailprotected]@
app.java.version[emailprotected]@
Note
这样只会过滤生产配置(换句话说,不会对src/test/resources
进行过滤)。
Tip
如果启用addResources
标志,则spring-boot:run
目标可以将src/main/resources
直接添加到 Classpath 中(用于热重载)。这样做避免了资源过滤和此功能。相反,您可以使用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>
Note
如果您在配置中使用标准的 Spring 占位符(例如${placeholder}
),则useDefaultDelimiters
属性非常重要。如果该属性未设置为false
,则可以通过构建扩展它们。
77.1.2 使用 Gradle 自动扩展属性
您可以通过配置 Java 插件的processResources
任务来自动扩展 Gradle 项目中的属性,如以下示例所示:
processResources {
expand(project.properties)
}
然后,您可以使用占位符来引用 Gradle 项目的属性,如以下示例所示:
app.name=${name}
app.description=${description}
Note
Gradle 的expand
方法使用 Groovy 的SimpleTemplateEngine
,它可以转换${..}
令牌。 ${..}
样式与 Spring 自己的属性占位符机制冲突。要将 Spring 属性占位符与自动扩展一起使用,请按以下方式对 Spring 属性占位符进行转义:\${..}
。
77.2 外部化 SpringApplication 的配置
SpringApplication
具有 bean 属性(主要是 setter),因此在创建应用程序时可以使用其 Java API 修改其行为。或者,您可以通过在spring.main.*
中设置属性来外部化配置。例如,在application.properties
中,您可能具有以下设置:
spring.main.web-application-type=none
spring.main.banner-mode=off
然后,Spring Boot 标语不会在启动时打印,并且应用程序也不会启动嵌入式 Web 服务器。
外部配置中定义的属性会覆盖用 Java API 指定的值,但用于创建ApplicationContext
的源除外。考虑以下应用程序:
new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF)
.sources(demo.MyApp.class)
.run(args);
现在考虑以下配置:
spring.main.sources=com.acme.Config,com.acme.ExtraConfig
spring.main.banner-mode=console
实际的应用程序* now *显示标语(被配置覆盖)并为ApplicationContext
使用三个源(按以下 Sequences):demo.MyApp
,com.acme.Config
和com.acme.ExtraConfig
。
77.3 更改应用程序外部属性的位置
默认情况下,来自不同来源的属性将以定义的 Sequences 添加到 Spring Environment
(有关确切 Sequences,请参见“ Spring Boot 功能”部分的“ 第 24 章,外部化配置”)。
增强和修改此 Sequences 的一种好方法是向应用程序源添加@PropertySource
注解。检查传递给SpringApplication
静态便捷方法的类和使用setSources()
添加的类,以查看它们是否具有@PropertySources
。如果确实如此,则将这些属性尽早添加到Environment
以便在ApplicationContext
生命周期的所有阶段中使用。以这种方式添加的属性的优先级低于使用默认位置(例如application.properties
),系统属性,环境变量或命令行添加的属性。
您还可以提供以下系统属性(或环境变量)来更改行为:
-
spring.config.name
(SPRING_CONFIG_NAME
):默认为application
作为文件名的根。 -
spring.config.location
(SPRING_CONFIG_LOCATION
):要加载的文件(例如 Classpath 资源或 URL)。为此文档设置了一个单独的Environment
属性源,可以通过系统属性,环境变量或命令行来覆盖它。
无论您在环境中设置什么,Spring Boot 总是如上所述加载application.properties
。默认情况下,如果使用 YAML,则 extensions 为'.yml'的文件也将添加到列表中。
Spring Boot 记录在DEBUG
级别加载的配置文件以及在TRACE
级别未找到的候选文件。
有关更多详细信息,请参见ConfigFileApplicationListener。
77.4 使用“简短”命令行参数
有些人喜欢使用--port=9000
而不是--server.port=9000
在命令行上设置配置属性。您可以通过使用application.properties
中的占位符来启用此行为,如以下示例所示:
server.port=${port:8080}
Tip
如果您从spring-boot-starter-parent
POM 继承,则maven-resources-plugins
的默认过滤器令牌已从${*}
更改为@
(即@[email protected]
而不是${maven.token}
),以防止与 Spring 样式的占位符冲突。如果直接为application.properties
启用了 Maven 过滤,则可能还需要更改默认过滤器令牌以使用other delimiters。
Note
在这种特定情况下,端口绑定可在 PaaS 环境(例如 Heroku 或 Cloud Foundry)中工作。在这两个平台中,PORT
环境变量是自动设置的,并且 Spring 可以绑定到Environment
属性的大写同义词。
77.5 对外部属性使用 YAML
YAML 是 JSON 的超集,因此是一种方便的语法,用于以分层格式存储外部属性,如以下示例所示:
spring:
application:
name: cruncher
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/test
server:
port: 9000
创建一个名为application.yml
的文件,并将其放在 Classpath 的根目录中。然后将snakeyaml
添加到您的依赖项中(Maven 坐标org.yaml:snakeyaml
,如果使用spring-boot-starter
则已经包含在内)。将 YAML 文件解析为 Java Map<String,Object>
(类似于 JSON 对象),然后 Spring Boot 展宽 Map,使其深一层,并具有句点分隔的键,这与许多人习惯使用 Java 的Properties
文件一样。
前面的示例 YAML 对应于以下application.properties
文件:
spring.application.name=cruncher
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/test
server.port=9000
有关 YAML 的更多信息,请参见“ Spring Boot 功能”部分中的“ 第 24.7 节“使用 YAML 代替属性””。
77.6 设置 ActiveSpring 轮廓
Spring Environment
为此提供了一个 API,但是您通常可以设置 System 属性(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
中设置 Active 配置文件,如以下示例所示:
spring.profiles.active=production
用这种方法设置的值将由“系统”属性或环境变量设置代替,而不是由SpringApplicationBuilder.profiles()
方法代替。因此,后一种 Java API 可用于扩充配置文件,而无需更改默认值。
有关更多信息,请参见“ Spring Boot 功能”部分中的“ 第 25 章,Profile”。
77.7 根据环境更改配置
YAML 文件实际上是由---
行分隔的文档序列,每个文档都分别解析为展平图。
如果 YAML 文档包含spring.profiles
键,则配置文件值(以逗号分隔的配置文件列表)将被送入 Spring Environment.acceptsProfiles()
方法。如果这些配置文件中的任何一个处于 Active 状态,则该文档将包含在最终合并中(否则,则不包含在此文档中),如以下示例所示:
server:
port: 9000
---
spring:
profiles: development
server:
port: 9001
---
spring:
profiles: production
server:
port: 0
在前面的示例中,默认端口为 9000.但是,如果名为“ development”的 Spring 概要文件处于 Active 状态,则该端口为 9001.如果“ production”为 Active,则该端口为 0.
Note
YAML 文档按照它们遇到的 Sequences 进行合并。以后的值将覆盖以前的值。
要对属性文件执行相同的操作,可以使用application-${profile}.properties
指定特定于配置文件的值。
77.8 发现外部属性的内置选项
Spring Boot 在运行时将application.properties
(或.yml
文件和其他位置)的外部属性绑定到应用程序中。在一个位置上没有(而且从技术上来说不是)所有受支持属性的详尽列表,因为贡献可能来自 Classpath 上的其他 jar 文件。
具有 Actuator 功能的正在运行的应用程序具有configprops
端点,该端点显示了通过@ConfigurationProperties
可用的所有绑定属性和可绑定属性。
附录包括一个application.properties示例,其中列出了 Spring Boot 支持的最常见属性。Authority 列表来自于在源代码中搜索@ConfigurationProperties
和@Value
注解以及偶尔使用Binder
。有关加载属性的确切 Sequences 的更多信息,请参见“ 第 24 章,外部化配置”。