✅ 一、变化的核心点
被 ConfigDataEnvironmentPostProcessor 替代:
在 Spring Boot 2.4 之前,ConfigFileApplicationListener 是加载配置文件的核心类,它通过实现 EnvironmentPostProcessor 接口,在环境准备阶段加载配置文件。
从 Spring Boot 2.4 开始,ConfigFileApplicationListener 被标记为 @Deprecated,其功能被新的 ConfigDataEnvironmentPostProcessor 所取代。
配置加载流程更加抽象化:
新的机制引入了 ConfigData 概念,将配置加载过程解耦为多个阶段:定位(location)、加载(load)、处理(process)等。
这使得配置加载可以支持更复杂的场景,例如从外部配置中心(如 Spring Cloud Config、Azure App Configuration)加载配置。
加载顺序和行为更符合预期:
旧版本中,YAML 多文档(multi-document)文件的处理逻辑较为混乱,容易出现配置覆盖顺序不明确的问题。
新版本中,文档将按定义顺序加载,后定义的属性会覆盖先定义的同名属性,与 .properties 文件的行为一致。
支持更灵活的配置路径和激活机制:
新增了 spring.config.activate.on-profile 属性,用于在配置文件中更明确地激活特定 profile 的属性。
支持 spring.config.import 机制,允许从外部资源导入配置。
✅ 二、高版本中 application.yaml 的加载流程
触发事件:
应用启动时,EventPublishingRunListener 会广播 ApplicationEnvironmentPreparedEvent 事件。
ConfigDataEnvironmentPostProcessor 监听该事件并开始处理配置。
解析配置位置:
优先级顺序(从高到低)为:
spring.config.additional-location
spring.config.location
默认搜索路径(classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/)。
加载配置文件:
使用 PropertySourceLoader 接口加载配置文件,具体实现类包括:
YamlPropertySourceLoader:用于 .yml 和 .yaml 文件。
PropertiesPropertySourceLoader:用于 .properties 和 .xml 文件。
处理 Profile 和多文档:
根据 spring.profiles.active 激活对应 profile 的配置。
YAML 多文档按顺序加载,后定义的属性覆盖前定义的同名属性。
✅ 三、是否"错误"?
不是错误,而是设计演进。
旧版本中,ConfigFileApplicationListener 的设计存在以下问题:
难以扩展,配置加载逻辑耦合度高。
多文档 YAML 文件处理逻辑不清晰,容易引发配置覆盖顺序的误解。
新版本通过引入 ConfigDataEnvironmentPostProcessor 和 ConfigData 概念,解决了这些问题,使配置加载更加清晰、灵活。
✅ 四、总结
Spring Boot 配置加载机制对比表
表格
| 对比项 | Spring Boot < 2.4 | Spring Boot ≥ 2.4 |
|---|---|---|
| 配置加载核心类 | ConfigFileApplicationListener |
ConfigDataEnvironmentPostProcessor |
| 实现接口 | ApplicationListener<ApplicationEnvironmentPreparedEvent> |
EnvironmentPostProcessor |
| 执行时机 | 环境准备事件触发时 | Environment 后置处理阶段 |
| 在启动流程中的位置 | 晚于 EnvironmentPostProcessor | 早于事件发布 |
| 配置文件读取入口 | onApplicationEvent |
postProcessEnvironment |
| 配置来源定位 | getSearchLocations() |
ConfigDataLocationResolver |
| 多 Profile 控制 | spring.profiles.active/include |
新增 spring.config.activate.on-profile |
| 导入外部配置 | 不支持 spring.config.import |
支持 import: optional:, configtree: 等 |
| 加载优先级控制 | 较固定、易混乱 | 更清晰、可扩展 |