返回正文当
简体中文
SpringBoot多环境配置
凌晨3点,线上报警炸了——生产环境的数据库连成了测试库。你猜怎么着?spring.profiles.active 的值在打包时被意外覆盖了。这种低级错误听起来像是新手才会犯的?别急,等你踩过我这几个坑,就知道SpringBoot的多环境配置远没application.yml里写两行配置那么简单。
当@ActiveProfiles遇上Maven Profile:谁说了算?
那次压测前,我在本地用@ActiveProfiles("stress")跑测试用例,结果连上的却是dev环境的Mock服务。排查发现:Maven的-Pprod参数悄悄覆盖了我的注解设置。
根因:SpringBoot的Profile加载顺序暗藏玄机
- 命令行参数(
--spring.profiles.active) - JVM系统参数(
-Dspring.profiles.active) @ActiveProfiles注解- Maven Profile的
spring.profiles.active属性(通过resources过滤)
错误写法:
java
@SpringBootTest
@ActiveProfiles("stress") // 会被Maven Profile覆盖
class OrderServiceTest { ... }1
2
3
2
3
正确解法:加@TestPropertySource硬核指定:
java
@TestPropertySource(properties = "spring.profiles.active=stress")
@SpringBootTest
class OrderServiceTest { ... }1
2
3
2
3
对比效果:
- 原方式:测试通过率92%(被Maven干扰)
- 修正后:100%稳定复现压测场景
include的陷阱:属性覆盖的“俄罗斯套娃”
我们团队的 application-prod.yml 里有这么一段:
yml
spring:
profiles:
include: security,metrics1
2
3
2
3
本意是引入安全监控配置,结果某次发版后
根因:include的配置文件会按声明顺序覆盖主文件属性,而application-metrics.yml里恰好有:
yml
server:
port: 8081 # 被security配置里的8080覆盖了1
2
2
避坑姿势:
- 用
spring.config.import替代(SpringBoot 2.4+) - 永远在
include的子配置里加spring.config.group隔离命名空间
环境变量 vs 配置文件:谁的优先级更高?
K8s集群里某个
yml
env:
- name: SPRING_DATASOURCE_URL
value: jdbc:postgresql://old-db:5432/mydb1
2
3
2
3
冷知识:SpringBoot的环境变量注入会自动转换命名风格:
SPRING_DATASOURCE_URL→spring.datasource.url- 且优先级高于
application.yml
紧急修复方案:
bash
# 启动时用命令行参数覆盖
java -jar app.jar --spring.datasource.url=${NEW_DB_URL}1
2
2
避坑清单:多环境配置的七寸在哪里
- Profile激活顺序:记住命令行 > JVM参数 > 注解 > 文件配置,测试时用
@TestPropertySource一锤定音 - 属性覆盖的隐式规则:
include的配置文件是从前往后覆盖,同名属性后者胜出 - 环境变量的魔鬼细节:K8s的
env会悄无声息地覆盖你的.yml配置 - 配置加载的默认行为:
spring.config.location指定目录时,该目录下的application.yml不会被自动加载(必须显式声明文件名) - 占位符的延迟解析:
${DB_HOST:localhost}在@Value注入时能解析,但在@ConfigurationProperties类里可能还是字面量
最后的救命稻草
当所有配置都乱套时,用这个命令打印最终生效的配置源:
bash
java -jar your-app.jar --debug | grep "Config file application" -A 201
这次踩坑让我明白:SpringBoot的“约定优于配置”是把双刃剑——95%的时候它让你爽到飞起,剩下5%的极端情况能让你通宵。
V 0.13.16 |
基于 MIT Licensed版权所有 © 2009- 2026 CMONO.NET
本站访客数
--次 本站总访问量
--人次 