属性和配置

本节包含有关设置和读取属性和配置设置及其与 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,则需要在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)
	}

}

或到SpringApplicationBuildersources(…​)方法。

  • 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。应用程序源是:

  1. MyApplication(来自代码)

  2. MyDatabaseConfig(来自外部配置)

  3. MyJmsConfig(来自外部配置)

更改应用程序外部属性的位置

默认情况下,来自不同源的属性会按照定义的顺序添加到 Spring Environment中(有关确切顺序,请参阅“Spring Boot 功能”部分中的外部化配置)。

您还可以提供以下系统属性(或环境变量)来更改行为。

  • spring.config.nameSPRING_CONFIG_NAME):默认为application作为文件名的根。

  • spring.config.locationSPRING_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)或 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 和属性文件(有关详细信息,请参阅使用多文档文件),可以根据活动配置文件有条件地激活这些文件。

如果文档包含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 文件。

具有执行器功能的正在运行的应用程序具有一个configprops端点,该端点显示通过@ConfigurationProperties可用的所有已绑定和可绑定属性。

附录包含一个application.properties示例,其中包含 Spring Boot 支持的最常见属性列表。最终列表来自搜索@ConfigurationProperties@Value注释以及偶尔使用Binder的源代码。有关加载属性的确切顺序的更多信息,请参阅外部化配置