Spring Boot通过spring.profiles.active显式指定激活环境配置文件,未设置时仅加载application.yml;优先级为命令行参数>环境变量>application.yml;配置文件按顺序覆盖而非合并;@Profile控制Bean注册,与配置文件加载机制独立。

Spring Boot怎么指定激活哪个application-{env}.yml
靠spring.profiles.active这个配置项决定加载哪个环境文件,它不是“自动识别”,而是必须显式声明。没设它,默认只加载application.yml,application-dev.yml这类文件压根不会被读取。
常见错误现象:application-prod.yml写了数据库密码,但启动后还是连的application.yml里的测试地址——八成是忘了配spring.profiles.active,或者配在了错的地方。
- 优先级顺序:命令行参数 > 系统环境变量 >
application.yml里写的spring.profiles.active - 命令行最可靠:
java -jar app.jar --spring.profiles.active=prod - 环境变量写法:
SPRING_PROFILES_ACTIVE=prod(注意大小写,Linux/macOS区分) - 别在
application.yml里用@profile@占位符——那是Maven资源过滤用的,Spring Boot不认
application.yml和application-{env}.yml的覆盖规则
不是“合并”,是“覆盖”:Spring Boot先加载application.yml,再按spring.profiles.active顺序加载对应application-{env}.yml,后者同名属性会把前者盖掉。
使用场景:基础配置(端口、日志路径)放application.yml,敏感或差异化配置(数据库URL、Redis地址)放application-prod.yml。
立即学习“Java免费学习笔记(深入)”;
- 多个环境同时激活:
--spring.profiles.active=dev,feature-redis,加载顺序就是列表顺序,后加载的覆盖前一个 - 如果
application-dev.yml里没写server.port,就沿用application.yml里的值;写了就替换 - 注意YAML缩进:
spring:下必须空格缩进,profiles:和active:不能顶格,否则解析失败报Invalid YAML
为什么@Profile("prod")注解的Bean没生效
因为@Profile只控制Bean是否注册进IoC容器,不控制配置文件加载。两者是独立机制:配置文件靠spring.profiles.active触发加载,Bean靠运行时激活的profile匹配才创建。
容易踩的坑:以为加了@Profile("prod")就等于“只有prod环境才跑这段代码”,结果spring.profiles.active=dev时,这个Bean根本没实例化,但其他没加@Profile的Bean照样跑,导致NPE或逻辑错乱。
- 确认当前激活的profile:
Environment.getActiveProfiles()打印出来看,别靠猜 -
@Profile("!test")这种否定写法可以,但别嵌套太深,可读性差 - 如果Bean依赖的配置项(比如
@Value("${db.url}"))在application-dev.yml里没定义,而spring.profiles.active=dev,那即使Bean被创建了,也会因配置缺失启动失败
打包后切换环境还总出错?检查这三个地方
本地跑得通,JAR包一上线就报Could not resolve placeholder 'xxx',大概率是环境隔离没做实,配置没打进包或没被正确读到。
- 确认
application-{env}.yml在JAR包的BOOT-INF/classes/目录下(用jar -tf app.jar | grep application查) - Maven打包时别用
<resources><excludes></excludes></resources>误删了application-*.yml - 外置配置优先级更高:如果启动时加了
--spring.config.location=file:/opt/config/,那它下面的application.yml会覆盖JAR包内的所有配置,包括profile设置
profile不是魔法开关,它只是告诉Spring“去加载哪些配置+注册哪些Bean”。哪一步断了,哪一步就失效。最常漏的是启动参数没传、YAML缩进错了、或者外置配置把profile重置了。











