Spring——Springcloud/Spring项目加载文件配置顺序

825 阅读6分钟

摘要

本文详细阐述了 Spring Cloud 和 Spring Boot 项目中配置文件的加载顺序。Spring Cloud 项目因引入 bootstrap.yml 和远程配置中心,加载顺序更复杂。其顺序依次为命令行参数、SPRING_APPLICATION_JSON、系统属性、操作系统环境变量、远程配置中心、bootstrap.yml、本地 application.yml(按特定顺序)、jar 包内 application.yml、@PropertySource 注解配置文件和默认配置。bootstrap.yml 用于启动阶段配置,application.yml 用于主要业务配置。还探讨了远程配置中心、如何确保本地 application.yml 不被远程覆盖以及相关总结。Spring Boot 项目配置文件加载顺序相对简单,包括默认顺序、@PropertySource 加载外部配置、多文件加载和单元测试时的配置等。

1. SpringCloud项目配置文件加载顺序

在 Spring Cloud 项目中,配置文件的加载顺序比普通 Spring Boot 项目更复杂,主要是因为 bootstrap.yml 和 远程配置中心 的加入。

1.1. Spring Cloud 配置文件加载顺序

Spring Cloud 的配置加载顺序 从高到低 如下:

  1. 命令行参数(最高优先级)
  2. SPRING_APPLICATION_JSON(环境变量或 -Dspring.application.json)
  3. 系统属性(System.getProperties())
  4. 操作系统环境变量(System.getenv())
  5. 远程 Spring Cloud Config 配置中心(如果启用)
  6. bootstrap.properties / bootstrap.yml(优先级高于 application.yml)
  7. 本地 application.properties / application.yml(按以下顺序)
    • file:./config/(外部 config 目录)
    • file:./(项目根目录)
    • classpath:/config/(resources/config/ 目录)
    • classpath:/(resources/ 目录)
  1. 打包在 jar 内的 application.properties / application.yml
  2. @PropertySource 注解的配置文件
  3. 默认配置(Spring 内置的默认值)

1.2. bootstrap.yml 和 application.yml 的区别

配置文件加载时机作用适用场景
bootstrap.yml最先加载(比 application.yml早)用于 Spring Boot 启动阶段的配置,如远程配置中心、加密密钥、多环境动态配置Spring Cloud 项目(使用 Spring Cloud Config时)
application.yml在 bootstrap.yml之后加载用于应用的主要业务配置,如数据库、日志、端口、服务名称等所有 Spring Boot 和 Spring Cloud 项目

1.3. 远程 Spring Cloud Config 配置中心

如果项目启用了 Spring Cloud Config(远程配置中心),那么:

  1. 远程配置会覆盖本地 application.yml 和 application.properties。
  2. 如果远程配置中心启用了 native 模式(本地文件存储),它的优先级相当于 bootstrap.yml ,但仍然会覆盖 application.yml。
  3. 本地 application.yml 仍然有效,但优先级低于远程配置,除非使用 spring.cloud.config.override-none=true 来禁用远程配置覆盖。

1.4. 如何确保本地 application.yml 不被远程覆盖?

如果不想让远程配置覆盖本地配置:

spring:
  cloud:
    config:
      override-none: true  # 让本地配置优先,不被远程覆盖

如果需要让本地配置部分覆盖远程配置:

spring:
  cloud:
    config:
      allow-override: true   # 允许本地覆盖远程配置
      override-system-properties: false  # 避免系统属性被覆盖
  • bootstrap.yml 优先级高于 application.yml,用于读取远程配置、加密密钥、动态环境变量等。
  • 远程配置中心的配置 优先级比 本地 application.yml 更高,可以通过 spring.cloud.config.override-none=true 调整。
  • application.properties 比 application.yml 先加载,如果两者有相同的 key,application.properties 的值会覆盖 application.yml 的值。
  • 外部 config/ 目录下的配置文件优先级比 classpath:/ 下的高,这样可以在不修改 jar 的情况下更新配置。

1.5. SpringCloud项目总结

  • bootstrap.yml 优先级高于 application.yml,用于读取远程配置、加密密钥、动态环境变量等。
  • 远程配置中心的配置 优先级比 本地 application.yml 更高,可以通过 spring.cloud.config.override-none=true 调整。
  • application.properties 比 application.yml 先加载,如果两者有相同的 key,application.properties 的值会覆盖 application.yml 的值。
  • 外部 config/ 目录下的配置文件优先级比 classpath:/ 下的高,这样可以在不修改 jar 的情况下更新配置。

1.6. spring cloud 项目中bootstrap.yml 没有 会去加载application.yml

在 Spring Cloud 项目中,如果 没有 bootstrap.yml,Spring 仍然会按照 普通 Spring Boot 项目的加载顺序 来加载 application.yml,但会缺少 bootstrap.yml 处理的特殊功能。

1.6.1. bootstrap.yml 的作用

bootstrap.yml 主要用于 Spring Cloud 相关的初始化配置,它比 application.yml 先加载,通常用于:

  1. Spring Cloud Config 远程配置中心的连接信息
  2. 动态环境配置(如 spring.profiles.active )
  3. 加密/解密(如 spring.cloud.config.server.encrypt.enabled=true )
  4. 自定义 PropertySource (如 Nacos、Apollo)

如果 bootstrap.yml缺失,但应用依赖了远程配置中心(如 Spring Cloud Config Server),那么:

  • 远程配置将不会被加载
  • 应用可能无法正确启动

1.6.2. 没有 bootstrap.yml,Spring Cloud 会如何加载配置?

如果 bootstrap.yml不存在,Spring Boot 仍然会加载 application.yml,但不会提前初始化 Spring Cloud 组件,导致:

  1. 远程配置中心(Spring Cloud Config Server)不会生效
  2. Spring Cloud 相关配置(如 spring.cloud.* )不会在应用启动前被解析
  3. application.yml 仍然会按照正常的 Spring Boot 加载顺序生效

1.6.3. application.yml 是否可以代替 bootstrap.yml?

可以,但有一定限制:

  • 你可以把 bootstrap.yml 里的配置放到 application.yml,但它会比远程配置中心的配置优先级低,导致某些 Spring Cloud 组件可能无法正常初始化。
  • 解决方案:
    • 如果不用远程配置中心:可以直接把 bootstrap.yml 的内容合并到 application.yml,一般不会有问题。
    • 如果需要远程配置,但不想用 bootstrap.yml,可以用 spring.config.import 手动指定:
spring:
  config:
    import: "optional:configserver:http://config-server:8888"

这样即使没有 bootstrap.yml,Spring Boot 仍然可以加载远程配置。

1.6.4. 推荐的做法

场景是否需要 bootstrap.yml?解决方案
普通 Spring Boot 项目❌ 不需要直接使用 application.yml
使用 Spring Cloud Config 远程配置✅ 需要放 spring.cloud.config.uri在 bootstrap.yml
使用 Nacos/Apollo 作为配置中心✅ 需要bootstrap.yml配置 spring.cloud.nacos.config.server-addr
不想使用 bootstrap.yml,但需要远程配置⚠️ 可选在 application.yml里用 spring.config.import

1.6.5. spring cloud 项目中bootstrap.yml、application.yml总结

  • 如果没有 bootstrap.yml ,Spring Cloud 仍然会加载 application.yml,但不会预加载远程配置中心的配置。
  • bootstrap.yml 主要用于 Spring Cloud 组件的初始化,特别是远程配置相关功能。如果你的项目不依赖远程配置,可以直接用 application.yml。
  • 可以用 spring.config.import 代替 bootstrap.yml,但部分 Spring Cloud 组件可能无法正确初始化。

2. Spring Boot项目配置文件加载顺序

2.1. Spring Boot 默认的加载顺序

Spring Boot 会按照以下顺序加载配置(从高优先级到低优先级):

  1. 命令行参数(最高优先级)
  2. SPRING_APPLICATION_JSON(环境变量或系统属性中的 JSON 配置)
  3. 系统属性(System.getProperties())
  4. 操作系统环境变量(System.getenv())
  5. RandomValuePropertySource(用于生成随机值)
  6. 外部配置文件(如 application.properties 或 application.yml):
    • config/ 目录下的文件(如 config/application.yml)
    • 项目根目录下的文件(如 application.yml)
    • classpath:/config/ 目录下的文件
    • classpath:/ 目录下的文件
  1. 打包在 jar 内的 application.properties 或 application.yml(最低优先级)

2.2. @PropertySource 加载的外部配置

  • 在 Java 配置类中使用 @PropertySource 可以加载指定路径的 properties 文件,例如:
@Configuration
@PropertySource("classpath:custom.properties")
public class AppConfig {
}
  • @PropertySource 加载的配置优先级比 application.properties 低,但比默认 application.properties 位置的文件优先级高。

2.3. @PropertySources 多文件加载

  • 如果有多个 @PropertySource,后加载的会覆盖先加载的值:
@PropertySources({
    @PropertySource("classpath:config1.properties"),
    @PropertySource("classpath:config2.properties")
})
    • config2.properties 中的配置会覆盖 config1.properties 中相同的 key。

2.4. @TestPropertySource (单元测试时的配置)

  • 在 Spring Boot 测试时,@TestPropertySource 指定的文件和属性会覆盖默认 application.properties 的值:
@SpringBootTest
@TestPropertySource(locations = "classpath:test.properties")
public class MyTest {
}

博文参考