java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot配置文件合并

SpringBoot将配置文件合并的方法详解

作者:步行cgn

配置文件合并是指 Spring Boot 在启动时,会从多个来源读取配置,将所有配置项汇总成一个统一的 PropertySource 集合,形成一个完整的配置环境,本文给大家具体介绍一下SpringBoot将配置文件合并的方法,需要的朋友可以参考下

在 Spring Boot 中,配置文件不是“要么用这个,要么用那个”的单一选择,而是多个配置文件可以同时存在,并按优先级合并成最终的配置。这就是配置文件的合并机制。

一、合并的定义

配置文件合并是指 Spring Boot 在启动时,会从多个来源读取配置,将所有配置项汇总成一个统一的 PropertySource 集合,形成一个完整的配置环境。当一个配置项在多个来源中出现时,根据优先级决定最终使用哪个值。

二、合并的参与方

Spring Boot 启动时,以下来源的配置会被合并:

  1. 命令行参数(最高优先级)
  2. 操作系统环境变量
  3. JVM 系统属性-D 参数)
  4. application-{profile}.yml(Profile 特定的配置)
  5. application.yml(默认配置)
  6. application-{profile}.properties(Profile 特定的配置)
  7. application.properties(默认配置)
  8. @PropertySource 加载的自定义配置文件
  9. 默认值(最低优先级)

三、合并规则

3.1 后加载覆盖先加载

高优先级的配置会覆盖低优先级的同名配置。同一优先级下,后加载的覆盖先加载的。

示例

application.yml 配置了 server.port=8080,而 application-dev.yml 配置了 server.port=9090。当激活 dev Profile 时,application-dev.yml 后加载,最终 server.port 的值是 9090

3.2 同文件内的合并

YAML 多文档块(---

同一个 YAML 文件中,--- 分隔的文档块会按顺序加载,后加载的覆盖前面的。

# 第一部分:默认配置
server:
  port: 8080
---
# 第二部分:dev Profile
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 9090

激活 dev 时,server.port9090

YAML 与 properties 共存

同一个键在 application.ymlapplication.properties 中都出现时,properties 优先级更高。PropertiesPropertySourceLoaderYamlPropertySourceLoader 的加载顺序决定了这个结果。

3.3 Map/对象的合并

当同一个键在多个配置文件中都出现时,是“覆盖”还是“合并”?这取决于类型:

基本类型(String、Number、Boolean)

直接覆盖:后加载的值替换先加载的值。

对象类型

对象内的字段是逐层合并的,不是整体覆盖。

# application.yml
app:
  name: myapp
  features:
    cache: true
# application-dev.yml
app:
  features:
    logging: true

合并后的结果是:

app:
  name: myapp
  features:
    cache: true
    logging: true

features 对象下的字段合并了,而不是整体覆盖。

列表/数组类型

列表的处理与对象不同。当两个配置文件中都有同一个列表键时,默认会整体替换,而不是追加元素。

# application.yml
servers:
  - server1
  - server2
# application-prod.yml
servers:
  - prod-server1
  - prod-server2

合并后 servers 的值为 [prod-server1, prod-server2],完全替换了默认值。如果希望追加,需要在代码层面处理。

3.4 属性来源的覆盖顺序

具体的覆盖顺序(从高到低):

  1. 命令行参数(--server.port=8081
  2. 环境变量(SERVER_PORT=8081
  3. JVM 系统属性(-Dserver.port=8081
  4. 外部 application-{profile}.ymlconfig/ 目录下)
  5. 外部 application.ymlconfig/ 目录下)
  6. 内部 application-{profile}.yml(classpath 根目录)
  7. 内部 application.yml(classpath 根目录)
  8. 外部 application-{profile}.properties
  9. 外部 application.properties
  10. 内部 application-{profile}.properties
  11. 内部 application.properties
  12. @PropertySource 自定义配置文件(按声明顺序,后声明的覆盖前面的)

四、Profile 的合并逻辑

Profile 是 Spring Boot 多环境配置的核心机制。当激活多个 Profile 时,它们的配置会按顺序合并。

4.1 单个 Profile

# application.yml
server:
  port: 8080

# application-dev.yml
server:
  port: 9090

激活 dev 时,server.port9090

4.2 多个 Profile

当激活多个 Profile 时,它们按照激活的顺序加载,后面加载的 Profile 配置覆盖前面的。

# 激活 dev 和 prod
--spring.profiles.active=dev,prod

加载顺序:application-dev.yml 先加载,application-prod.yml 后加载。后加载的覆盖先加载的。

五、实战示例

5.1 多环境配置合并

application.yml(默认配置):

app:
  name: myapp
  version: 1.0
  features:
    cache: true
    logging: true
  server:
    port: 8080

application-dev.yml(开发环境):

app:
  features:
    logging: false
  server:
    port: 8081

application-prod.yml(生产环境):

app:
  name: production-app
  server:
    port: 80
  features:
    cache: true
    logging: false

激活 dev 时的合并结果:

app:
  name: myapp
  version: 1.0
  features:
    cache: true
    logging: false      # dev 覆盖
  server:
    port: 8081          # dev 覆盖

激活 prod 时的合并结果:

app:
  name: production-app  # prod 覆盖
  version: 1.0
  features:
    cache: true
    logging: false      # prod 覆盖
  server:
    port: 80            # prod 覆盖

5.2 外部配置文件与内部配置文件合并

# 外部配置文件(优先级更高)
/config/application.yml
# 内部配置文件(classpath 根目录)
application.yml

5.3 命令行覆盖配置

java -jar myapp.jar --app.name=cli-app

即使 application.yml 中配置了 app.name,命令行参数会覆盖它。

六、常见问题与排查

6.1 配置不生效

检查是否有高优先级的配置覆盖了你的配置。例如,环境变量、命令行参数、Profile 特定配置文件。

在启动时开启 debug 模式:

debug: true

或启动参数:--debug,查看配置加载详情和自动配置报告。

6.2 配置被意外覆盖

使用 @ConfigurationProperties 绑定到对象,通过日志打印配置值,确认最终生效的配置。

6.3 列表被替换而非追加

这是 YAML 合并的默认行为。如果希望追加,可以在代码中使用 Spring 的 @ConfigurationProperties 配合 @Value 手动处理。

@ConfigurationProperties(prefix = "servers")
public class ServerProperties {
    private List<String> list = new ArrayList<>();
    // getter/setter
}

七、总结

配置来源优先级覆盖方式
命令行参数最高覆盖
环境变量 / JVM 系统属性覆盖
Profile 特定配置中高覆盖默认配置
默认配置最低被覆盖

配置文件合并的规则可以概括为:高优先级覆盖低优先级,后加载覆盖先加载,对象类型合并字段,列表类型整体替换。

理解这些规则,就能准确预判最终生效的配置,避免因配置覆盖导致的意外行为。在排查配置问题时,查看 debug 模式下的配置加载日志是最有效的定位方式。

以上就是SpringBoot将配置文件合并的方法详解的详细内容,更多关于SpringBoot配置文件合并的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文