Spring Boot 配置文件加载优先级你知道吗?
- 标签:Spring Boot、后端
🏛 业务架构师
Spring Boot 配置加载优先级按"外部覆盖内部、命令行最高"的原则排列(高 → 低):
- 命令行参数(
--server.port=8081)与SPRING_APPLICATION_JSON; SPRING_CONFIG_ADDITIONAL_LOCATION指定的外部文件;- 操作系统环境变量(K8s ConfigMap/Secret 的注入通道);
- jar 包外的 application.{yml,properties}(./config/ 子目录优先于当前目录);
- jar 包内的 application.{yml,properties};
- 包内 Profile 变体(application-prod.yml)覆盖对应基础文件(同级生效);
@PropertySource等代码内指定来源最低。
核心心智模型:越靠近运行环境、越后加载的优先级越高——镜像内置默认值,部署环境按需覆盖。
业务架构师视角,这套优先级直接翻译成环境管理策略:
- 一份镜像走所有环境:基础配置打进 jar(内层),数据库地址、密钥、开关用 K8s 环境变量/ConfigMap 注入(外层覆盖)——环境差异不产生镜像差异,发布可重复性才有保证;
- 紧急运维通道:生产救火时用命令行参数覆盖某项配置重启,比改配置重新构建快一个数量级——但要留审计;
- 常见事故:本地 yml 残留覆盖生产配置、环境变量命名错(
SERVER_PORT有效但要符合 relaxed binding 规则)——配置变更纳入评审与变更单管理,是配置事故率最低的治理手段。
🏗 系统架构师
从高到低的主线(记住「越靠近运行时优先级越高」):
- 命令行参数(
--server.port=8080); - SPRING_APPLICATION_JSON;
- 环境变量(
SERVER_PORT——K8s 注入的主通道); - Java System properties;
- profile 特定的应用内/外配置文件;
- 应用内
application.{yml|properties}; @PropertySource等补充源;- 默认值(代码里的缺省)。
两个细节:同目录下 properties 优先于 yml;application-{profile}.yml 优先于 application.yml。
架构原则:这套优先级支撑的是一份制品贯穿 dev 到 prod——差异全部由外层(环境变量、配置中心)覆盖,制品永不重打包;relaxed binding 让 spring.datasource.url 与 SPRING_DATASOURCE_URL 自动映射,K8s ConfigMap/Secret 直接对接。
排障口诀:配置不生效,先看 actuator 的 env 端点(注意脱敏)的最终生效值与来源链,不靠猜。
💻 全栈开发专家
核心原则:外层覆盖内层、晚读覆盖先读、profile 专属覆盖通用。高频顺序(从高到低):
- 命令行参数:
--server.port=9090 SPRING_APPLICATION_JSON- 操作系统环境变量:
SERVER_PORT(K8s env/ConfigMap 注入走这层,relaxed binding 自动做名字转换) - jar 外部配置文件:
./config/子目录又高于./同级 - jar 内部配置文件:application-{profile}.yml 覆盖 application.yml
记忆抓手:命令行 > 环境变量 > 外部文件 > 内部文件;同名时 profile 版赢。
验证手段(必会):Actuator /actuator/env——能看到每个 key 实际命中哪一层来源(origin 链),排查"改了配置没生效"的神器,比重启试错快得多。
真实坑:环境变量 relaxed binding 的命名转换(SMS_APPID 对应 sms.appId);新项目统一用 spring.config.import: nacos:xxx 管配置中心导入;测试环境用 --spring.config.additional-location=/etc/app/ 追加配置目录。另外注意启动时打的 The following 1 profile is active 日志,profile 没激活导致的"配置不生效"占比很高。