Automatic Property Expansion with Spring Boot – 使用Spring Boot的自动属性扩展

最后修改: 2017年 8月 31日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’ll explore the property expansion mechanism provided by Spring through Maven and Gradle build methods.

在这篇文章中,我们将探讨Spring通过Maven和Gradle构建方法提供的属性扩展机制。

2. Maven

2.Maven

2.1. Default Configuration

2.1.默认配置

For Maven projects using the spring-boot-starter-parent, there is no need for extra configurations to make use of property expansions:

对于使用spring-boot-starter-parent的Maven项目,不需要额外配置就能利用属性扩展。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.3.RELEASE</version>
</parent>

Now we can expand our project’s properties using @…@ placeholders. Here is an example of how we may save the project’s version taken from Maven, into our properties:

现在我们可以使用 @…@占位符扩展项目的属性。下面是一个例子,说明我们如何将Maven中的项目版本保存到我们的属性中。

expanded.project.version=@project.version@
expanded.project.property=@custom.property@

We can only use these expansions within configuration files matching these patterns:

我们只能在符合这些模式的配置文件中使用这些扩展。

  • **/application*.yml
  • **/application*.yaml
  • **/application*.properties

2.2. Manual Configuration

2.2.手动配置

In the absence of the spring-boot-starter-parent parent, we’ll need to configure this filtering and expansion manually. We’ll need to include resources element into the <build> section of our pom.xml file:

在没有spring-boot-starter-parent父类的情况下,我们需要手动配置这种过滤和扩展。我们需要在<build>文件的pom.xml部分包含resources元素。

<resources>
    <resource>
        <directory>${basedir}/src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>**/application*.yml</include>
            <include>**/application*.yaml</include>
            <include>**/application*.properties</include>
         </includes>
    </resource>
</resources>     

And in the <plugins>:

而在<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>

In cases where it’s required to use the standard placeholders of type ${variable.name} we’ll need to set useDefaultDelimeters to true, and your application.properties will look like this:

在需要使用${variable.name}类型的标准占位符的情况下,我们需要将useDefaultDelimeters设置为true,你的application.properties将看起来像这样。

expanded.project.version=${project.version}
expanded.project.property=${custom.property}

3. Gradle

3.Gradle

3.1. Standard Gradle Solution

3.1.标准的Gradle解决方案

The Gradle solution from the Spring Boot documentation is not 100% compatible with the Maven property filtering and expansion.

Spring Boot文档中的Gradle 解决方案与Maven的属性过滤和扩展并非100%兼容。

To allow us to use the property expansion mechanism, we’ll need to include the following code into build.gradle:

为了让我们能够使用属性扩展机制,我们需要在build.gradle中包含以下代码。

processResources {
    expand(project.properties)
}

This is a limited solution with the following differences from the Maven default configuration:

这是一个有限的解决方案,与Maven的默认配置有以下区别。

  1. Does not support properties with dots (e.g. user.name). Gradle understands dots as object property delimiters
  2. Filters all the resource files and not just a specific set of configuration files
  3. Uses the default dollar-sign placeholders ${…} thus conflicting with the standard Spring placeholders

3.2. Maven Compatible Solution

3.2.与Maven兼容的解决方案

For us to replicate the standard Maven solution and make use of the @…@ style placeholders, we need to add the following code to our build.gradle:

为了复制标准的Maven解决方案,利用@…@风格的占位符,我们需要在build.gradle中添加以下代码。

import org.apache.tools.ant.filters.ReplaceTokens
processResources {
    with copySpec {
        from 'src/main/resources'
        include '**/application*.yml'
        include '**/application*.yaml'
        include '**/application*.properties'
        project.properties.findAll().each {
          prop ->
            if (prop.value != null) {
                filter(ReplaceTokens, tokens: [ (prop.key): prop.value])
                filter(ReplaceTokens, tokens: [ ('project.' + prop.key): prop.value])
            }
        }
    }
}

This will resolve all the project’s properties. We still cannot define properties with dots (e.g. user.name) in the build.gradle, but now we can use gradle.properties file to define properties in the standard Java properties format, and it also supports properties with dots (e.g database.url).

这将解决项目的所有属性。我们仍然不能在 build.gradle中定义带点的属性(如user.name),但现在我们可以使用gradle.properties文件,以标准的Java属性格式定义属性,它也支持带点的属性(如database.url)。

This build filters only the project configuration files and not all the resources, and it’s 100% compatible with the Maven solution.

这种构建方式只过滤项目配置文件,不过滤所有资源,而且与Maven解决方案100%兼容。

4. Conclusion

4.结论

In this quick tutorial, we saw how to automatically expand Spring Boot properties using both Maven and Gradle build methods and how we can easily migrate from one to the other.

在这个快速教程中,我们看到了如何使用Maven和Gradle两种构建方法自动扩展Spring Boot属性,以及如何从一种方法轻松迁移到另一种方法。

The complete source example can be found over on GitHub.

完整的源码实例可以在GitHub上找到over