Spring——Springcloud/Spring项目加载文件配置顺序
摘要
本文详细阐述了 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 的配置加载顺序 从高到低 如下:
- 命令行参数(最高优先级)
SPRING_APPLICATION_JSON
(环境变量或-Dspring.application.json
)- 系统属性(
System.getProperties()
) - 操作系统环境变量(
System.getenv()
) - 远程 Spring Cloud Config 配置中心(如果启用)
bootstrap.properties / bootstrap.yml
(优先级高于application.yml
)- 本地
application.properties / application.yml
(按以下顺序)
-
file:./config/
(外部config
目录)file:./
(项目根目录)classpath:/config/
(resources/config/
目录)classpath:/
(resources/
目录)
- 打包在
jar
内的application.properties / application.yml
@PropertySource
注解的配置文件- 默认配置(Spring 内置的默认值)
1.2. bootstrap.yml
和 application.yml
的区别
配置文件 | 加载时机 | 作用 | 适用场景 |
| 最先加载(比 早) | 用于 Spring Boot 启动阶段的配置,如远程配置中心、加密密钥、多环境动态配置 | Spring Cloud 项目(使用 时) |
| 在 之后加载 | 用于应用的主要业务配置,如数据库、日志、端口、服务名称等 | 所有 Spring Boot 和 Spring Cloud 项目 |
1.3. 远程 Spring Cloud Config 配置中心
如果项目启用了 Spring Cloud Config(远程配置中心),那么:
- 远程配置会覆盖本地
application.yml
和application.properties
。 - 如果远程配置中心启用了
native
模式(本地文件存储),它的优先级相当于bootstrap.yml
,但仍然会覆盖application.yml
。 - 本地
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
先加载,通常用于:
- Spring Cloud Config 远程配置中心的连接信息
- 动态环境配置(如
spring.profiles.active
) - 加密/解密(如
spring.cloud.config.server.encrypt.enabled=true
) - 自定义
PropertySource
(如 Nacos、Apollo)
如果 bootstrap.yml
缺失,但应用依赖了远程配置中心(如 Spring Cloud Config Server),那么:
- 远程配置将不会被加载
- 应用可能无法正确启动
1.6.2. 没有 bootstrap.yml
,Spring Cloud 会如何加载配置?
如果 bootstrap.yml
不存在,Spring Boot 仍然会加载 application.yml
,但不会提前初始化 Spring Cloud 组件,导致:
- 远程配置中心(Spring Cloud Config Server)不会生效
- Spring Cloud 相关配置(如
spring.cloud.*
)不会在应用启动前被解析 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. 推荐的做法
场景 | 是否需要 ? | 解决方案 |
普通 Spring Boot 项目 | ❌ 不需要 | 直接使用 |
使用 Spring Cloud Config 远程配置 | ✅ 需要 | 放 在 |
使用 Nacos/Apollo 作为配置中心 | ✅ 需要 |
配置 |
不想使用 ,但需要远程配置 | ⚠️ 可选 | 在 里用 |
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 会按照以下顺序加载配置(从高优先级到低优先级):
- 命令行参数(最高优先级)
SPRING_APPLICATION_JSON
(环境变量或系统属性中的 JSON 配置)- 系统属性(
System.getProperties()
) - 操作系统环境变量(
System.getenv()
) RandomValuePropertySource
(用于生成随机值)- 外部配置文件(如
application.properties
或application.yml
):
-
config/
目录下的文件(如config/application.yml
)- 项目根目录下的文件(如
application.yml
) classpath:/config/
目录下的文件classpath:/
目录下的文件
- 打包在 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 {
}