基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

Spring Boot 配置文件的加载优先级是怎样的?

知识点图片

Spring Boot 的配置文件加载机制遵循 “后加载覆盖先加载”(Later overrides earlier)的原则,也就是优先级高的配置会覆盖优先级低的配置

如果同一个属性在多个地方都配置了,Spring Boot 会使用优先级最高的那个值。

以下是详细的优先级顺序说明:

一、 配置文件路径的优先级 (由高到低)

Spring Boot 默认会扫描以下 4 个位置的配置文件(如 application.propertiesapplication.yml):

  1. file:./config/
    • 项目运行目录下的 config 子目录(优先级最高)。
    • 通常用于生产环境部署时,存放由于安全或环境原因需要外部化的配置。
  2. file:./
    • 项目运行的根目录。
    • 通常用于临时覆盖 jar 包内部的配置。
  3. classpath:/config/
    • Classpath (Resource) 下的 config 包目录。
  4. 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 还可以从命令行参数、环境变量等读取配置。以下是最常用的整体优先级排序(从高到低,上面的覆盖下面的):

  1. 命令行参数 (Command Line Arguments)
    • 例如:java -jar app.jar --server.port=9090
    • 这是最高的,可以覆盖所有文件配置。
  2. Java 系统属性 (Java System Properties)
    • 例如:java -Dserver.port=9090 -jar app.jar
  3. 操作系统环境变量 (OS Environment Variables)
    • 例如在 Docker 或 K8s 中设置的 SERVER_PORT=9090
  4. jar 包外部application-{profile}.properties/yml
  5. jar 包内部application-{profile}.properties/yml
  6. jar 包外部application.properties/yml
  7. jar 包内部application.properties/yml
  8. @PropertySource 注解
    • 在配置类上引用的属性文件。
  9. 默认属性
    • 通过 SpringApplication.setDefaultProperties 设置的默认值。

五、 举个例子

假设我们要配置 server.port,不同位置配置如下:

  1. 命令行启动: --server.port=8001
  2. 项目根目录/config/application-prod.yml: server.port: 8002
  3. 项目根目录/application.yml: server.port: 8003
  4. Jar包内/classpath/application-prod.yml: server.port: 8004
  5. 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 (外部的默认配置 > 内部的默认配置)

核心记忆口诀

  1. 命令 > 环境 > 文件
  2. >
  3. Profile > Default
00:00
00:00