Spring Boot 配置文件加载优先级是怎样的?多环境配置如何切换?
结论先行:Spring Boot 的配置来自多个 PropertySource,规则是“后面的覆盖前面的”。命令行参数 > Java 系统属性 > 环境变量 > profile 专属文件 > 无 profile 文件 > 默认值。多环境用 application-{profile}.yml 与 spring.profiles.active 切换,profile 文件永远覆盖同名基础配置。
一、加载顺序(优先级从高到低,常用段)
| 优先级 | 来源 | 说明 |
|---|---|---|
| 高 | 命令行参数 | --server.port=8081 |
| ↑ | Java 系统属性 / SPRING_APPLICATION_JSON | 部署注入 |
| ↑ | 操作系统环境变量 | 大写+下划线,如 SERVER_PORT |
| ↑ | application-{profile}.yml(外部) | 同目录/外部 config/ |
| ↑ | application-{profile}.yml(classpath 内) | jar 内 profile 文件 |
| ↑ | application.yml(外部) | 覆盖 jar 内默认 |
| 低 | application.yml(classpath 内) | 最后兜底 |
外部查找路径由高到低:./config/ → ./ → classpath /config/ → classpath /,后加载者优先级更高。
二、多环境切换
# application.yml
spring:
profiles:
active: prod # 激活 prod
group:
prod: prod-db,prod-mq # 激活组(2.4+)
- 激活方式:配置文件 spring.profiles.active、启动参数
--spring.profiles.active=prod、环境变量 SPRING_PROFILES_ACTIVE,后两者可覆盖配置文件; - profile 文件命名
application-{profile}.yml,与基础 application.yml 同名键会被覆盖; - yml 单文件多文档:用
---分段 +spring.config.activate.on-profile声明段落归属(Boot 2.4+,替代旧版 spring.profiles); - 代码侧用 @Profile("dev") 控制 Bean 是否注册,配合 @ConfigurationProperties 做环境差异配置。
三、生产实践注意
- 敏感信息(口令、密钥)不进配置文件,用环境变量/配置中心/密钥管理注入;
- profile 名统一约定 dev/test/staging/prod,禁用启动时缺省未知 profile;
- 若配置文件不生效,优先按“命令行 > 环境变量 > profile 文件 > 基础文件”的次序排查覆盖关系。
常见追问 / 记忆点
- 追问:同名配置出现在多个来源听谁的?答:优先级高的覆盖低的,命令行最高。
- 追问:docker/K8s 里怎么传环境?答:通过 env 注入大写下划线变量,或用 SPRING_APPLICATION_JSON 一次注入多个。
- 记忆点:外部覆盖内部、profile 覆盖默认、命令行最大;多环境 = active + {profile} 文件。