72. 属性和配置

72.1 在构建时自动扩展属性

您可以使用现有的构建配置自动扩展它们,而不是对项目的构建配置中也指定的某些属性进行硬编码。在 Maven 和 Gradle 中都是可能的。

72.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 占位符(例如${foo}),则useDefaultDelimiters属性非常重要。如果该属性未设置为false,则可以通过构建扩展它们。

72.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 属性占位符。

72.2 外部化 SpringApplication 的配置

SpringApplication具有 bean 属性(主要是 setter),因此在创建应用程序时可以使用其 Java API 修改其行为。或者,您可以使用spring.main.*中的属性将配置外部化。例如。在application.properties中,您可能有。

spring.main.web-environment=false
spring.main.banner-mode=off

然后 Spring Boot 标语将不会在启动时打印,并且该应用程序也不是 Web 应用程序。

Note

上面的示例还演示了灵活绑定如何允许在属性名称中使用下划线(_)和破折号(-)。

外部配置中定义的属性会覆盖通过 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

实际的应用程序现在将现在显示标语(被配置覆盖)并为ApplicationContext使用 3 个源(按此 Sequences):demo.MyAppcom.acme.Configcom.acme.ExtraConfig

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

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

增强和修改此内容的一种好方法是向应用程序源添加@PropertySourceComments。将检查传递给SpringApplication静态便捷方法的类以及使用setSources()添加的类,以查看它们是否具有@PropertySources,如果存在,则将这些属性尽早添加到Environment以便在ApplicationContext生命周期的所有阶段中使用。以这种方式添加的属性的优先级低于使用默认位置(例如application.properties),系统属性,环境变量或命令行添加的属性。

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

无论您在环境中进行什么设置,Spring Boot 都会始终如上所述加载application.properties。如果使用 YAML,则默认情况下还将将 extensions 为'.yml'的文件添加到列表中。

Spring Boot 记录在DEBUG级别加载的配置文件以及在TRACE级别未找到的候选文件。

有关更多详细信息,请参见ConfigFileApplicationListener

72.4 使用'short'命令行参数

有些人喜欢使用--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属性的大写同义词。

72.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,使其深度为 1 级,并具有句点分隔的键,这很像人们习惯使用 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.6 节“使用 YAML 代替属性” *。

72.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 *。

72.7 根据环境更改配置

YAML 文件实际上是由---行分隔的文档序列,每个文档都分别解析为展平图。

如果 YAML 文档包含spring.profiles键,则将配置文件值(以逗号分隔的配置文件列表)馈入 Spring Environment.acceptsProfiles(),并且如果其中任何一个配置文件处于 Active 状态,则该文件将包含在最终合并中(否则不包含)。

Example:

server:
    port: 9000
---

spring:
    profiles: development
server:
    port: 9001

---

spring:
    profiles: production
server:
    port: 0

在此示例中,默认端口为 9000,但是如果 Spring 概要文件“ development”处于 Active 状态,则该端口为 9001,如果“ production”为 Active,则其为 0.

YAML 文档按照它们遇到的 Sequences 进行合并(因此,较新的值将覆盖较早的值)。

要对属性文件执行相同的操作,可以使用application-${profile}.properties指定特定于配置文件的值。

72.8 发现外部属性的内置选项

Spring Boot 在运行时将application.properties(或.yml)(以及其他位置)的外部属性绑定到应用程序中。在一个位置上没有(而且从技术上来说不是)所有受支持属性的详尽列表,因为贡献可能来自 Classpath 上的其他 jar 文件。

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

附录包括一个application.properties示例,其中列出了 Spring Boot 支持的最常见属性。最终列表来自于在源代码中搜索@ConfigurationProperties@Value注解以及偶尔使用RelaxedPropertyResolver

上一章 首页 下一章