
Spring Boot 的核心设计之一是“约定优于配置”(Convention Over Configuration),这使得它能够根据默认值和用户提供的配置快速启动应用程序。然而,在实际开发中,应用的配置可能来自多个来源。理解这些配置来源的优先级非常重要,以便在配置冲突时确保程序按预期运行。
本文将详细介绍 Spring Boot 3 中的各种配置来源及其优先级,并提供实际案例和最佳实践。
Spring Boot 3 的配置有以下几种来源(按照优先级从高到低排列):
java -D 系统属性application.properties 或 application.yml src/main/resources 中的默认配置application-{profile}.properties 或 application-{profile}.yml@PropertySource 注解为了方便展示各种配置来源的优先级,下面将采用优先级从低到高的顺序依次展示各种配置的生效情况。
当启动项目没有提供某个属性时,则使用 Spring Boot 的默认值。
示例:
如果未配置 server.port,则使用默认端口 8080。

@PropertySource 注解通过 @PropertySource 注解加载的配置文件优先级较低,但可以用于加载自定义的配置文件。
示例:
在 src/main/resources 目录下创建 custom.properties 文件:
server.port=8081创建一个配置类,用 @PropertySource 加载自定义配置文件。
@Configuration
@PropertySource("classpath:custom.properties")
public class CustomConfig {
}启动项目,服务端口为自定义配置的8081。

application.properties 或 application.yml)application.properties 或 application.yml 是最常用的配置来源。它们可以存在于 src/main/resources 中,也可以作为外部文件。
加载顺序:
src/main/resources)。application 开头,默认加载 application.properties 或 application.yml。/config 子目录示例:
server:
port: 8082
Spring Boot 支持根据 Profile 加载特定的配置文件,例如 application-prod.yml 或 application-dev.yml,这种方式可以帮助开发者轻松管理和切换开发、测试、生产等不同环境的配置。
默认未激活 Profile 情况下, application.yml 优先级高于 application-dev.yml。

激活 Profile 的方式:
命令行参数:
java -jar app.jar --spring.profiles.active=prod环境变量:
export SPRING_PROFILES_ACTIVE=prod配置文件中设置:
spring:
profiles:
active: prodIDEA配置 Active profiles:

优先级:
Profile-specific 文件的配置优先于 application.yml


使用场景:
操作系统级别的环境变量优先于配置文件,但低于命令行参数和系统属性。
示例: 在 Linux/Mac 上设置环境变量:
export SERVER_PORT=8084在 Windows 上设置环境变量:
set SERVER_PORT=8084或 IDEA设置环境变量

启动应用后,Spring Boot 会自动解析环境变量 SERVER_PORT 并将其映射到 server.port 属性。

注意: 环境变量的名称为大写字母,并用下划线 _ 替代点 .。
使用场景:
java -D)通过 JVM 参数 -D 传递的系统属性次于命令行参数,但优先于其他来源。
示例:
java -Dserver.port=8085 -jar app.jar或者通过 IDEA 设置 JVM 参数:
-Dserver.port=8085
此命令会将 server.port 设置为 8085:

使用场景:
通过命令行参数传递的配置优先级最高。这通常用于在启动应用程序时临时修改配置,例如更改端口号或激活特定 Profile。
示例:
java -jar app.jar --server.port=8086或者通过IDEA设置命令行参数:

此命令将优先于所有其他配置来源设置端口号为 8086。

使用场景:
bootstrap.yml 和 application.yml 都用于配置应用程序的属性,但它们的作用和优先级不同。以下是两者的详细对比和优先级说明:
bootstrap.yml 的作用bootstrap.yml 在 application.yml 之前加载。spring.cloud.config.*。# bootstrap.yml
spring:
application:
name: my-application
cloud:
config:
uri: http://config-server:8888
enabled: trueapplication.yml 的作用application.yml 在 bootstrap.yml 加载之后。# application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password在属性加载的优先级上:
bootstrap.yml 优先于 application.yml。 bootstrap.yml 是 Spring Boot 启动时的引导配置,加载更早。bootstrap.yml 中加载后,会合并到 Spring 的环境中。application.yml 中的属性和 bootstrap.yml 冲突: application.yml 中的属性会覆盖 bootstrap.yml 中的属性(除非 bootstrap.yml 的属性被标记为不可覆盖,如某些 Spring Cloud 配置)。bootstrap.yml 的场景:
spring.application.name、spring.cloud.config.*。application.yml 的场景:
特性 | bootstrap.yml | application.yml |
|---|---|---|
加载时机 | 更早 | 稍后 |
用途 | 引导配置,主要用于配置中心、初始化 | 应用主要配置 |
覆盖优先级 | 属性优先级较低,但加载较早 | 属性优先级较高 |
推荐使用场景 | Spring Cloud Config、注册中心配置 | 数据源、业务逻辑相关配置 |
从上面的示例可以看出,当同一个属性来自多个来源时,Spring Boot 按优先级选择高的配置。例如:
配置文件中 application.yml 设置:
server:
port: 8085同时命令行指定 --server.port=8086。
最终优先级选择结果为 8086,因为命令行参数优先。
application.yml。Spring Boot 3 提供了丰富的配置机制,开发者可以根据实际需求选择合适的方式进行配置管理。了解这些配置来源的优先级,有助于在复杂项目中快速定位问题,提升项目的可维护性。