Skip to content

Spring Boot 配置文件加载优先级你知道吗? ​

  • 标签:Spring Boot、后端

🏛 业务架构师 ​

Spring Boot 配置加载优先级按"外部覆盖内部、命令行最高"的原则排列(高 → 低):

  1. 命令行参数(--server.port=8081)与 SPRING_APPLICATION_JSON;
  2. SPRING_CONFIG_ADDITIONAL_LOCATION 指定的外部文件;
  3. 操作系统环境变量(K8s ConfigMap/Secret 的注入通道);
  4. jar 包外的 application.{yml,properties}(./config/ 子目录优先于当前目录);
  5. jar 包内的 application.{yml,properties};
  6. 包内 Profile 变体(application-prod.yml)覆盖对应基础文件(同级生效);
  7. @PropertySource 等代码内指定来源最低。

核心心智模型:越靠近运行环境、越后加载的优先级越高——镜像内置默认值,部署环境按需覆盖。

业务架构师视角,这套优先级直接翻译成环境管理策略:

  1. 一份镜像走所有环境:基础配置打进 jar(内层),数据库地址、密钥、开关用 K8s 环境变量/ConfigMap 注入(外层覆盖)——环境差异不产生镜像差异,发布可重复性才有保证;
  2. 紧急运维通道:生产救火时用命令行参数覆盖某项配置重启,比改配置重新构建快一个数量级——但要留审计;
  3. 常见事故:本地 yml 残留覆盖生产配置、环境变量命名错(SERVER_PORT 有效但要符合 relaxed binding 规则)——配置变更纳入评审与变更单管理,是配置事故率最低的治理手段。

🏗 系统架构师 ​

从高到低的主线(记住「越靠近运行时优先级越高」):

  1. 命令行参数(--server.port=8080);
  2. SPRING_APPLICATION_JSON;
  3. 环境变量(SERVER_PORT——K8s 注入的主通道);
  4. Java System properties;
  5. profile 特定的应用内/外配置文件;
  6. 应用内 application.{yml|properties};
  7. @PropertySource 等补充源;
  8. 默认值(代码里的缺省)。

两个细节:同目录下 properties 优先于 yml;application-{profile}.yml 优先于 application.yml。

架构原则:这套优先级支撑的是一份制品贯穿 dev 到 prod——差异全部由外层(环境变量、配置中心)覆盖,制品永不重打包;relaxed binding 让 spring.datasource.url 与 SPRING_DATASOURCE_URL 自动映射,K8s ConfigMap/Secret 直接对接。

排障口诀:配置不生效,先看 actuator 的 env 端点(注意脱敏)的最终生效值与来源链,不靠猜。

💻 全栈开发专家 ​

核心原则:外层覆盖内层、晚读覆盖先读、profile 专属覆盖通用。高频顺序(从高到低):

  1. 命令行参数:--server.port=9090
  2. SPRING_APPLICATION_JSON
  3. 操作系统环境变量:SERVER_PORT(K8s env/ConfigMap 注入走这层,relaxed binding 自动做名字转换)
  4. jar 外部配置文件:./config/ 子目录又高于 ./ 同级
  5. 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 没激活导致的"配置不生效"占比很高。