1. 概述
在Spring项目中创建配置属性时,我们通常会将它们拆分到多个文件中。按不同Spring Profile拆分属性是常见做法。
但随着属性数量增多,这些文件会逐渐包含大量重复内容,可读性变差。手动清理既耗时又容易出错。
本教程将介绍一个名为Spring Properties Cleaner的Maven插件,它能帮你自动化整理属性文件,让配置管理重回正轨。
2. 示例
2.1. 一些属性文件
假设我们有两个Profile:dev和prod。先看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.host
和redis_host
中。这让我们能提取更多通用配置到application.properties。
提交变更后继续。
7. 提取到通用属性
添加common
配置启用属性提取:
<configuration>
...
<common>full</common>
</configuration>
7.1. 使用full模式提取通用文件
common
有三种模式:full
、consistent
和multiple
。**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插件:
- ✅ 在构建中监控属性文件问题
- ✅ 逐步增强配置强度(排序/简化)
- ✅ 最终提取通用配置到中心文件
将此插件作为代码检查工具,既能清理现有配置,又能防止问题复现。
示例代码可在GitHub获取。