Spring Boot 配置源详解(完整版)

一、配置源加载顺序与优先级
| 配置源类型 | 优先级顺序(从高到低) | 对应配置类/接口 | 是否可覆盖 | 典型文件/来源 |
|---|---|---|---|---|
命令行参数(--key=value) | 1(最高) | SimpleCommandLinePropertySource(org.springframework.core.env) | 是 | 启动参数(如 java -jar app.jar --server.port=9090) |
| SPRING_APPLICATION_JSON | 2 | MapPropertySource(org.springframework.core.env) | 是 | 环境变量或系统属性(如 -Dspring.application.json={...}) |
| 系统环境变量 | 3 | SystemEnvironmentPropertySource(org.springframework.core.env) | 是 | 操作系统环境变量(如 export APP_NAME=myapp) |
| @PropertySource 注解 | 4 | PropertySourcesPropertyResolver(org.springframework.core.env) | 是 | 代码中指定的资源路径(如 classpath:custom.properties) |
| ServletConfig 初始化参数 | 5 | ServletConfigPropertySource(org.springframework.boot.env) | 是 | Web 容器配置(如 Tomcat 的 context-param) |
| ServletContext 初始化参数 | 6 | ServletContextPropertySource(org.springframework.boot.env) | 是 | Web 容器配置(如 Tomcat 的 init-param) |
| JNDI 环境变量 | 7 | JndiPropertySource(org.springframework.core.env) | 是 | JNDI 服务器配置(如 java:comp/env) |
随机属性(random.*) | 8 | RandomValuePropertySource(org.springframework.boot.env) | 否 | 自动生成随机值(如 random.number=12345) |
类路径 application.properties/.yml | 9 | YamlPropertySourceLoader, PropertiesPropertySourceLoader(org.springframework.boot.env) | 否 | src/main/resources/application.properties |
资源目录 application.properties | 10 | ResourcePropertySource(org.springframework.core.env) | 是 | 外部目录(如 /config/application.properties) |
Profile 特定配置(如 application-dev.properties) | 11 | ProfileSpecificPropertySource(org.springframework.boot.env) | 是 | src/main/resources/application-{profile}.properties |
外置配置文件(如 external-config/application.properties) | 12 | ExternalConfigPropertySource(org.springframework.boot.env) | 是 | 外置路径(如 /opt/config/application.properties) |
二、配置源加载流程详解
-
初始化 Environment:
- Spring Boot 启动时,通过
SpringApplication创建Environment对象(类型StandardEnvironment)。 Environment管理所有配置源的集合PropertySources。
- Spring Boot 启动时,通过
-
加载引导配置:
- 通过
PropertySourceBootstrapConfiguration加载bootstrap.yml/properties(用于配置加密、外部配置文件路径等)。
- 通过
-
逐层加载配置源:
- 使用
PropertySourceLoader加载不同格式的配置文件(如 YAML、Properties):// 例如加载 YAML 文件 YamlPropertySourceLoader loader = new YamlPropertySourceLoader(); Resource resource = new ClassPathResource("application.yml"); PropertySource<?> yamlSource = loader.load("application", resource, 0); environment.getPropertySources().addLast(yamlSource);
- 使用
-
合并配置源:
- 按优先级顺序合并所有
PropertySource,高优先级覆盖低优先级的同名属性。
- 按优先级顺序合并所有
三、配置转换过程
-
属性解析:
- 通过
ConfigurationPropertySources将所有PropertySource转换为ConfigurationPropertySource:// 示例:解析属性路径 ConfigurationPropertyName name = ConfigurationPropertyName.of("server.port");
- 通过
-
绑定到 Bean:
- 使用
Binder将属性值绑定到@ConfigurationProperties注解的 Bean:@ConfigurationProperties(prefix = "app") public class AppProperties {private String name;private int timeout;// getters/setters }@SpringBootApplication @EnableConfigurationProperties(AppProperties.class) // 必须启用 public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} }
- 使用
-
类型转换:
- 通过
ConversionService处理类型转换(如String转Integer):@Bean public ConversionService conversionService() {GenericConversionService service = new GenericConversionService();service.addConverter(String.class, Integer.class, s -> Integer.parseInt(s));return service; }
- 通过
四、嵌套与替换规则
-
变量替换:
- 支持
${key}语法引用其他属性:# application.properties base.url=http://example.com api.url=${base.url}/api
- 支持
-
优先级覆盖:
- 高优先级配置源的值覆盖低优先级的同名属性:
# application.properties: server.port=8080 # 命令行参数:--server.port=9090 → 最终值为 9090
- 高优先级配置源的值覆盖低优先级的同名属性:
-
多文档合并:
- 同名属性按加载顺序依次覆盖,最终保留最高优先级的值。
五、配置源对比表
| 配置源类型 | 位置/来源 | 是否可覆盖 | 典型使用场景 | 代码示例 |
|---|---|---|---|---|
| 命令行参数 | 启动参数 | 是 | 运行时动态配置 | java -jar app.jar --server.port=9090 |
| SPRING_APPLICATION_JSON | 环境变量或系统属性 | 是 | 简单 JSON 配置 | -Dspring.application.json='{ "server": { "port": 9090 } }' |
| 系统环境变量 | 操作系统环境变量 | 是 | 生产环境全局配置 | export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/db |
| @PropertySource 注解 | 代码指定的资源路径 | 是 | 内嵌特定配置文件 | ```java |
| \n@Configuration\n@PropertySource(“classpath:custom.properties”)\n``` | ||||
| 外置配置文件 | 文件系统(如 /config) | 是 | 生产环境外部配置 | /config/application.properties |
| Profile 特定配置 | 类路径或外置路径 | 是 | 不同环境差异化配置 | application-dev.properties |
六、代码示例
1. 系统环境变量覆盖
# 操作系统环境变量设置:
export APP_NAME="ProductionApp"
// 使用 @Value 注入
@Value("${APP_NAME}")
private String appName;
2. 随机属性使用
# application.properties
random.seed=12345
@Value("${random.number}")
private int randomNum; // 自动生成随机数
3. JNDI 配置示例
// JNDI 配置(需容器支持)
@Resource(name = "java:comp/env/jdbc/datasource")
private DataSource dataSource;
4. 外置配置文件激活
# 启动命令指定配置路径:
java -jar app.jar --spring.config.location=file:/opt/config/application.properties
5. Profile 特定配置
# application-dev.properties
spring.datasource.url=jdbc:mysql://localhost:3306/dev
// 启动时指定 Profile:
java -jar app.jar --spring.profiles.active=dev
七、总结表格
| 配置源类型 | 优先级 | 对应类/接口 | 是否可覆盖 | 典型文件/来源 | 示例 |
|---|---|---|---|---|---|
| 命令行参数 | 高 | SimpleCommandLinePropertySource | 是 | 启动参数 | --server.port=9090 |
| 系统环境变量 | 中 | SystemEnvironmentPropertySource | 是 | 操作系统环境变量 | export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/db |
类路径 application.properties | 低 | PropertiesPropertySourceLoader | 否 | 内置资源路径 | src/main/resources/application.properties |
| 外置配置文件 | 中低 | ExternalConfigPropertySource | 是 | 外部文件路径 | /config/application.properties |
关键代码类参考
- 加载器:
YamlPropertySourceLoader,PropertiesPropertySourceLoader(org.springframework.boot.env) - 环境管理:
StandardEnvironment,ConfigurableEnvironment(org.springframework.core.env) - 绑定机制:
Binder,ConfigurationPropertyBindingPostProcessor(org.springframework.boot.context.properties)
通过上述流程,Spring Boot 实现了灵活且可扩展的配置管理能力,开发者可根据需求选择合适的配置源并控制优先级。