Spring Boot 配置文件的加载优先级是怎样的?
Spring Boot 的配置文件加载机制遵循 “后加载覆盖先加载”(Later overrides earlier)的原则,也就是优先级高的配置会覆盖优先级低的配置。
如果同一个属性在多个地方都配置了,Spring Boot 会使用优先级最高的那个值。
以下是详细的优先级顺序说明:
一、 配置文件路径的优先级 (由高到低)
Spring Boot 默认会扫描以下 4 个位置的配置文件(如 application.properties 或 application.yml):
file:./config/- 项目运行目录下的
config子目录(优先级最高)。 - 通常用于生产环境部署时,存放由于安全或环境原因需要外部化的配置。
- 项目运行目录下的
file:./- 项目运行的根目录。
- 通常用于临时覆盖 jar 包内部的配置。
classpath:/config/- Classpath (Resource) 下的
config包目录。
- Classpath (Resource) 下的
classpath:/- Classpath (Resource) 的根目录(优先级最低)。
- 这是我们开发时最常存放
application.properties的地方。
总结规律:
- 外部配置 优先级高于 内部配置(打入 Jar 包内的)。
- 子目录配置 优先级高于 根目录配置。
二、 Profile (环境) 配置的优先级
除了路径,Spring Boot 还区分“通用配置”和“特定环境配置”。
优先级规则:application-{profile}.properties > application.properties
即:带环境后缀的配置文件优先级高于不带后缀的默认配置文件。
- 例如:如果当前激活的是
dev环境,那么application-dev.properties中的配置会覆盖application.properties中的同名配置。 - 注意:如果不冲突,两者会互补(Merge)。
三、 文件后缀的优先级
如果在同一个目录下,既有 application.properties 又有 application.yml:
优先级规则:.properties > .yml (或 .yaml)
- Spring Boot 会优先加载
.properties文件。建议项目中统一使用一种格式,避免混淆。
四、 综合优先级 (宏观视角)
除了配置文件,Spring Boot 还可以从命令行参数、环境变量等读取配置。以下是最常用的整体优先级排序(从高到低,上面的覆盖下面的):
- 命令行参数 (Command Line Arguments)
- 例如:
java -jar app.jar --server.port=9090 - 这是最高的,可以覆盖所有文件配置。
- 例如:
- Java 系统属性 (Java System Properties)
- 例如:
java -Dserver.port=9090 -jar app.jar
- 例如:
- 操作系统环境变量 (OS Environment Variables)
- 例如在 Docker 或 K8s 中设置的
SERVER_PORT=9090。
- 例如在 Docker 或 K8s 中设置的
jar包外部 的application-{profile}.properties/ymljar包内部 的application-{profile}.properties/ymljar包外部 的application.properties/ymljar包内部 的application.properties/yml@PropertySource注解- 在配置类上引用的属性文件。
- 默认属性
- 通过
SpringApplication.setDefaultProperties设置的默认值。
- 通过
五、 举个例子
假设我们要配置 server.port,不同位置配置如下:
- 命令行启动:
--server.port=8001 - 项目根目录/config/application-prod.yml:
server.port: 8002 - 项目根目录/application.yml:
server.port: 8003 - Jar包内/classpath/application-prod.yml:
server.port: 8004 - Jar包内/classpath/application.yml:
server.port: 8005
最终生效结果:
- 如果启动命令是
java -jar app.jar --spring.profiles.active=prod --server.port=8001- 结果:8001 (命令行优先级最高)
- 如果启动命令是
java -jar app.jar --spring.profiles.active=prod(没有命令行指定端口)- 结果:8002 (外部的 profile 配置 > 内部的 profile 配置)
- 如果启动命令是
java -jar app.jar(默认 default 环境)- 结果:8003 (外部的默认配置 > 内部的默认配置)
核心记忆口诀
- 命令 > 环境 > 文件
- 外 > 内
- Profile > Default