必须用 -P 显式激活 Maven Profile,IDE 不识别 activeByDefault;资源需分两段配置并启用 filtering;Maven profile 与 spring.profiles.active 完全解耦;filter 路径须准确且大小写敏感,推荐直接在 profile 内定义 properties。

Profile 必须显式用 -P 激活,IDE 不会自动读取 pom.xml 里的 activeByDefault
IntelliJ 或 Eclipse 默认不认 pom.xml 里写的 <activeByDefault>true</activeByDefault>,哪怕你本地 clean install 看起来“生效”了,那也只是 IDE 缓存或上一次构建残留。真正可靠的激活方式只有一种:mvn clean package -Pdev(或 -Ptest、-Pprod)。
如果你在 IDE 里点“Maven → package”,它默认不传任何 -P 参数,结果就是:所有 profile 都没激活,${env} 变量为空,资源过滤失效,打包后 application.yml 里全是 ${db.url} 这类未替换的占位符。
- 必须在 Maven 运行配置中手动加参数,比如 IDEA 的 “Run Configuration” → “Command line” 填
clean package -Ptest - 不要依赖 IDE 的 “auto-import” 或 “always update snapshots” 来同步 profile —— 它们只管依赖,不管 profile 激活状态
-
<activation><os>或<file>这类隐式激活方式,在 CI/CD 或不同开发机上极易失效,一律禁用
resources 配置要分两段:先排除所有环境子目录,再单独包含当前 profile 对应目录
常见错误是只写一段 <resource>,比如:<directory>src/main/resources/${env}</directory>。这会导致 logback-spring.xml、banner.txt 等非环境专属文件全被漏掉,打出来的 jar 启动直接报错。
正确做法是用两段 <resource> 覆盖全部资源:
- 第一段:
<directory>src/main/resources</directory>+<excludes>排除dev/*、test/*、prod/* - 第二段:
<directory>src/main/resources/${env}</directory>,且不设<excludes> - 两段都必须加上
<filtering>true</filtering>,否则${xxx}不会替换
这样既能保留公共配置文件,又能精准叠加当前环境的 application.yml 和 application.properties。
Spring Boot 的 spring.profiles.active 和 Maven profile 是两套机制,别混着用
Maven profile 控制的是**打包时哪些文件进 jar、哪些占位符被替换**;而 spring.profiles.active 控制的是**运行时 Spring 加载哪个 application-prod.yml**。两者完全解耦。
典型翻车现场:
- 在
application-prod.yml里又写spring.profiles.active: prod—— 冗余且可能触发循环激活 - 以为
mvn clean package -Pprod就能让应用启动时自动走 prod profile —— 实际上它只是把src/main/resources/prod/application.yml打进了 jar,启动还得靠java -jar app.jar --spring.profiles.active=prod - 在
pom.xml里用 Maven filter 替换spring.profiles.active=${env}—— 这会让 application.yml 里写死 profile,失去运行时灵活性
建议:Maven 只负责替换数据库地址、API 域名等真实环境变量;spring.profiles.active 留给运维或启动脚本控制。
filter 文件路径写错或缺失,Maven 默认静默失败,${} 变成 ??? 或空字符串
当你在 <filters> 里引用 src/main/filters/dev.properties,但实际文件叫 Dev.properties 或放在 src/filters/ 下,Maven 不会报错,只会打印一句模糊日志:Filtering skipped for file,然后所有 ${db.url} 全变成空或 ???。
-
<filter>路径必须写全,推荐用相对路径:<filter>src/main/filters/${env}.properties</filter> - 文件必须放在
src/main/filters/(Maven 默认路径),大小写敏感,Linux 下DEV.properties≠dev.properties - 验证是否生效:检查
target/classes/application.yml,确认 ${} 已被替换成真实值;若仍是原样,优先查 filter 路径和文件是否存在
最稳妥的方式是跳过 external filter,直接用 <properties> 定义在 profile 内部,比如:<db.url>jdbc:mysql://localhost:3306/test</db.url>,然后在 resources 中直接引用 ${db.url} —— 简单、可控、无额外文件依赖。

















