1. 概述

在Spring项目中创建配置属性时,我们通常会将它们拆分到多个文件中。按不同Spring Profile拆分属性是常见做法

但随着属性数量增多,这些文件会逐渐包含大量重复内容,可读性变差。手动清理既耗时又容易出错。

本教程将介绍一个名为Spring Properties Cleaner的Maven插件,它能帮你自动化整理属性文件,让配置管理重回正轨。

2. 示例

2.1. 一些属性文件

假设我们有两个Profile:devprod。先看application-dev.properties

spring.datasource.url=jdbc:postgresql://${db_server}/mydatabase
spring.datasource.username=${USERNAME}
spring.datasource.password = ${PASSWORD}

redis_host=localhost

spring.redis.host=http://${redis_host}
spring.redis.port=6379

redis_host=localhost

spring.jpa.show-sql=true


upstream.host = myapp.dev.myorg.com

# upstream services
upstream.service.users.url=http://${upstream.host}/api/users
upstream.service.products.url=http://${upstream.host}/api/products

spring.redis.timeout=10000

再看application-prod.properties

spring.datasource.url=jdbc:postgresql://${db_server}/mydatabase
spring.datasource.username=${USERNAME}
spring.datasource.password = ${PASSWORD}

# upstream services
upstream.service.users.url=https://${upstream.host}/api/users
upstream.service.products.url=https://${upstream.host}/api/products

redis_host=azure.redis6a5d54.microsoft.com

spring.redis.host=https://${redis_host}
spring.redis.port=6379

upstream.host = myapp.prod.myorg.com

spring.redis.timeout=2000

接下来我们将清理这些文件。

2.2. 属性文件有什么问题?

这些文件存在以下典型问题:

  • redis_host在dev文件中重复出现
  • ✅ 属性格式不统一(有时name=value,有时name = value
  • ✅ 属性排序混乱(多个spring.redis配置分散在不同位置)
  • ✅ "upstream services"的URL列表结构相似,但因http/https差异无法共享
  • spring.datasource配置完全相同,可提取到通用文件

即使这些文件很短,手动优化也需要考虑很多细节。让我们用Spring Properties Cleaner自动化处理,并把它作为代码检查工具防止问题复现。

3. 将Spring Properties Cleaner添加到构建中

该插件可作为Maven插件使用。当检测到属性文件问题时,它会中断构建

pom.xml中添加最新版本

<plugin>
    <groupId>uk.org.webcompere</groupId>
    <artifactId>spring-properties-cleaner-plugin</artifactId>
    <version>1.0.6</version>
    <executions>
        <execution>
            <goals>
                <goal>scan</goal>
            </goals>
        </execution>
    </executions>
</plugin>

现在执行mvn compile,插件会报错:

$ mvn compile

...
[INFO] --- spring-properties-cleaner:1.0.3:scan (default) @ spring-properties-cleaner ---
[INFO] Executing scan on /Users/ashleyfrieze/dev/tutorials/maven-modules/maven-plugins/spring-properties-cleaner/src/main/resources
[ERROR] application-dev.properties: redis_host has duplicate values L5:'localhost',L10:'localhost'
[ERROR] File 'application-dev.properties' does not meet standard - have you run fix?
[ERROR] File 'application-prod.properties' does not meet standard - have you run fix?
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE

默认配置下,插件能检测到格式错误和重复键。

4. 修复重复项和格式

执行fix操作修复基础问题:

$ mvn spring-properties-cleaner:fix

通过版本控制查看application-dev.properties的变更:

清理重复项和重新格式化

⚠️ 强烈建议分阶段修复文件,每次修改后提交到版本控制系统。

默认配置下,插件移除了:

  • 文件开头和中间的多余空格
  • 重复的属性定义

现在文件已整理,Maven构建将恢复成功。但我们可以进一步配置插件优化更多方面。

5. 排序属性

添加排序配置:

<plugin>
    ...
    <artifactId>spring-properties-cleaner-plugin</artifactId>
    ...
    <configuration>
        <sort>clustered</sort>
    </configuration>
</plugin>

这里使用clustered排序模式(也可选sorted字母序)。clustered会保持原始顺序,但将相同前缀的属性聚集在一起。

重新运行fix后,application-prod.properties的变化:

属性重排序

排序效果

  • 所有spring开头的属性被聚集
  • upstream.host被提升到redis_host之前
  • redis_host保留在文件底部

检查所有文件的变更后提交,继续优化。

6. 内联前缀

当需要将通用配置提取到application.properties时,常遇到因占位符不完整导致的模式匹配问题。比如:

  • dev: upstream.service.users.url=http://${upstream.host}/api/users
  • prod: upstream.service.users.url=https://${upstream.host}/api/users

如果upstream.host能包含协议部分,这两个值就完全相同了。这时可用inlinePrefix配置:

<configuration>
    <inlinePrefix>https?://</inlinePrefix>
</configuration>

正则表达式https?://匹配http和https协议。查看application-prod.properties的变化:

内联前缀

现在http协议被合并到upstream.hostredis_host中。这让我们能提取更多通用配置application.properties

提交变更后继续。

7. 提取到通用属性

添加common配置启用属性提取:

<configuration>
    ...
    <common>full</common>
</configuration>

7.1. 使用full模式提取通用文件

common有三种模式:fullconsistentmultiple。**full模式要求属性在所有文件中完全相同才会被提取**。

其他模式风险较高:

  • consistent:提取在所有出现文件中相同的属性(可能意外包含特定Profile的配置)
  • multiple:提取出现多次且最常见的值(可能导致异常值被覆盖)

看看full模式的效果

创建了新的application.properties

spring.datasource.url=jdbc:postgresql://${db_server}/mydatabase
spring.datasource.username=${USERNAME}
spring.datasource.password=${PASSWORD}

spring.redis.host=${redis_host}
spring.redis.port=6379

# upstream services
upstream.service.users.url=${upstream.host}/api/users
upstream.service.products.url=${upstream.host}/api/products

application-dev.properties被大幅简化:

spring.redis.timeout=10000

spring.jpa.show-sql=true


redis_host=http://localhost


upstream.host=http://myapp.dev.myorg.com

application-prod.properties同样被简化。最后只需清理多余的空行。

7.2. 其他通用文件模式

  • full模式(最安全):仅当属性在所有Profile文件中完全相同时才提取
  • ⚠️ consistent模式:提取在所有出现文件中相同的属性(可能意外包含特定Profile的配置)
  • ⚠️ multiple模式:提取出现多次且最常见的值(如3个文件中2个为10000,1个为20000,则提取10000)

当移动不一致的属性时,需谨慎测试,避免意外覆盖Profile特定配置。

8. 清理垂直空白

使用whitespace配置控制空行:

<configuration>
    ...
    <whitespace>section</whitespace>
</configuration>

section模式会在不同前缀的属性块之间保留空行(也可选remove移除所有空行)。最终运行fix的效果:

清理垂直空白

现在属性文件已完全整洁有序

9. 结论

本教程展示了属性文件随项目增长可能出现的混乱问题。我们通过Spring Properties Cleaner插件:

  1. ✅ 在构建中监控属性文件问题
  2. ✅ 逐步增强配置强度(排序/简化)
  3. ✅ 最终提取通用配置到中心文件

将此插件作为代码检查工具,既能清理现有配置,又能防止问题复现

示例代码可在GitHub获取。


原始标题:Cleaning Spring Properties Files | Baeldung