跳过正文

技术手记 | Spring Boot 配置文件加载顺序深度解析

·201 字·1 分钟
陌白
作者
陌白
一只热爱技术的码农
目录

在Spring Boot应用开发中,配置文件是管理应用行为、数据库连接、服务端口等关键信息的枢纽。然而,当项目中存在多个配置文件时,它们的加载顺序和优先级就变得至关重要。理解这一机制可以帮助我们避免配置混乱,实现不同环境下的灵活部署。本文将带你深入了解Spring Boot配置文件的加载顺序与覆盖规则。

配置文件位置与优先级
#

Spring Boot 会从多个位置加载 application.propertiesapplication.yml 文件。下图直观地展示了这些位置以及它们默认的优先级顺序。

图例说明:

  • /myBoot:表示 JAR 包所在目录,目录名称可自定义。
  • /childDir:表示 JAR 包所在目录下 config 目录的子目录,目录名可自定义。
  • JAR:表示 Spring Boot 项目打包生成的 JAR 文件。
  • 其余带有“/”标识的目录的目录名称均不能修改。
  • 红色数字:表示该配置文件的优先级,数字越小优先级越高

从图中我们可以看出,Spring Boot 会同时加载 JAR 包内外的配置文件,并根据其所在位置确定优先级。

核心加载规则
#

Spring Boot 加载配置文件的顺序遵循一套清晰的规则,可以总结为以下几点:

  • 包外优先于包内:先加载 JAR 包外的配置文件,再加载 JAR 包内的配置文件。这使得我们可以不重新打包就修改线上应用的配置。
  • config 目录优先于根目录:在同一层级下(包外或包内),config 目录下的配置文件优先级高于根目录下的。
  • config 子目录更优先config 目录的子目录中的配置文件比 config 目录本身的优先级更高。
  • Profile 配置优先application-{profile}.properties/yml 格式的特定环境配置文件,其优先级高于默认的 application.properties/yml
  • 文件类型顺序:先加载 .properties 文件,再加载 .yml 文件。如果两个文件存在相同配置,后加载的会覆盖先加载的。

示例分析:配置覆盖与互补
#

现在,我们通过一个具体的例子来理解这些规则是如何协同工作的。

假设我们有以下配置文件:

  1. JAR 包外 application.yml:位于 /myBoot/application.yml (优先级3)
  2. JAR 包内 application.yml:位于 /JAR/application.yml (优先级5)
  3. JAR 包内 application-prod.yml:位于 /JAR/application-prod.yml

配置文件内容(推断):

  • JAR 包外 application.yml:
    server:
      servlet:
        context-path: /out-default
    spring:
      profiles:
        active: prod # 激活生产环境
    
  • JAR 包内 application.yml (默认配置):
    server:
      port: 8081
      servlet:
        context-path: /in-default
    
  • JAR 包内 application-prod.yml (生产环境配置):
    server:
      port: 8083
      servlet:
        context-path: /in-prod
    

加载与解析过程:

  1. 加载所有配置:Spring Boot 在启动时会加载全部的 5 个配置文件(此处示例中涉及3个)。其中,位于 JAR 包外的 application.yml 拥有最高的优先级。

  2. 激活 Profile:在 JAR 包外的 application.yml 中,通过 spring.profiles.active: prod 配置激活了生产环境(prod)Profile。这意味着 JAR 包内部的 application-prod.yml 文件会生效。

  3. 确定优先级顺序:此时,该项目中的有效配置文件优先级顺序为:

    JAR 包外 application.yml > JAR 包内 application-prod.yml > JAR 包内 application.yml

  4. 属性覆盖

    • application-prod.yml 的配置内容会覆盖 JAR 包内 application.yml 的配置内容。因此,端口号(port)从 8081 变为 8083,上下文路径(context-path)从 /in-default 变为 /in-prod
    • 接着,由于 JAR 包外的 application.yml 优先级最高,它会覆盖所有低优先级文件中的相同配置。因此,application-prod.yml 中的上下文路径 /in-prod 会被覆盖为 /out-default
  5. 形成互补配置

    • 对于 server.port 属性,application-prod.yml 中有定义(8083),而最高优先级的 JAR 包外 application.yml 中没有定义,所以最终生效的是 8083
    • 对于 server.servlet.context-path 属性,最高优先级的 JAR 包外 application.yml 中有定义(/out-default),所以它会覆盖其他所有文件中的定义,最终生效的是 /out-default

最终,应用启动后的有效配置为:端口号为 8083,上下文路径为 /out-default。这个结果是所有相关配置文件根据优先级规则进行属性覆盖和互补的结果。

总结
#

掌握 Spring Boot 配置文件的加载顺序是进行高效、灵活应用部署的关键。核心原则是“高优先级覆盖,低优先级互补”。通过将易变的配置放在 JAR 包外部,并善用 Profile 机制,我们可以轻松地在不同环境(开发、测试、生产)之间切换,而无需修改任何代码或重新打包,这极大地提升了开发和运维效率。

相关文章