1. Spring Boot配置优先级问题背景
在Spring Boot项目中,我们经常会遇到各种配置来源相互覆盖的问题。上周我在重构一个老项目时就踩了个坑:明明在application.yml里配置了server.port=8080,启动后却跑在了8090端口上。排查了半天才发现是同事在启动脚本里加了--server.port=8090参数。这种配置冲突问题在实际开发中屡见不鲜,今天我们就来彻底剖析Spring Boot的配置优先级机制。
Spring Boot支持多达17种配置源(从2.4.0版本开始),但日常开发中最常用的主要是以下四种:
- 命令行参数(如--server.port=8090)
- JVM系统属性(-Dserver.port=8090)
- 操作系统环境变量(SERVER_PORT=8090)
- 应用配置文件(application.yml/properties)
理解它们的加载顺序和覆盖关系,不仅能帮我们快速定位配置问题,还能灵活运用不同配置源来满足各种环境需求。比如在容器化部署时用环境变量覆盖配置,在本地调试时用命令行参数临时修改值等。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 配置源优先级深度解析
2.1 官方定义的优先级顺序
根据Spring Boot官方文档,配置源的优先级从高到低如下:
- 命令行参数(--key=value形式)
- 来自java:comp/env的JNDI属性
- Java系统属性(System.getProperties())
- 操作系统环境变量
- 仅在random.*中存在的RandomValuePropertySource
- 应用外部的配置文件(application-{profile}.properties/yml)
- 应用内部的配置文件
- 在@Configuration类上的@PropertySource注解
- 默认属性(通过SpringApplication.setDefaultProperties指定)
注意:实际开发中2、5、8、9这几种用得较少,我们今天重点分析前四种常见源的覆盖关系。
2.2 四种核心配置源的覆盖关系
通过一个具体案例来验证不同配置源的覆盖效果。假设我们要配置server.port属性:
yaml复制# applicati
