Spring Boot 配置加载优先级?

2025年 阅读约 15 分钟 面试指南 · Spring Boot

深入解析Spring Boot配置加载优先级:17个配置源从高到低排序、application.yml vs bootstrap.yml、命令行参数覆盖、配置中心优先级、多环境配置,附面试模拟问答。

一句话总结

Spring Boot 配置优先级从高到低:命令行参数 > 系统环境变量 > application-{profile}.yml(外部)> application-{profile}.yml(内部)> application.yml(外部)> application.yml(内部)。核心原则:越外部的配置优先级越高、越具体的配置优先级越高。外部配置(jar 包外)覆盖内部配置(jar 包内),profile 特定配置覆盖通用配置。

初级理解

配置优先级(从高到低)

# Spring Boot 配置优先级(数字越小优先级越高) # 1. 命令行参数(--server.port=8080) # 2. SPRING_APPLICATION_JSON(环境变量中的 JSON) # 3. JNDI 属性(java:comp/env) # 4. System.getProperties() # 5. 操作系统环境变量 # 6. RandomValuePropertySource(random.*) # 7. jar 包外部的 application-{profile}.yml # 8. jar 包内部的 application-{profile}.yml # 9. jar 包外部的 application.yml # 10. jar 包内部的 application.yml # 11. @PropertySource 注解 # 12. SpringApplication.setDefaultProperties() # 核心记忆 # 命令行 > 环境变量 > 外部 profile > 内部 profile > 外部默认 > 内部默认

多环境配置

# application.yml(公共配置) server: port: 8080 # application-dev.yml(开发环境) server: port: 8081 # application-prod.yml(生产环境) server: port: 80 # 激活环境 spring: profiles: active: dev # 使用 application-dev.yml # 最终 server.port = 8081(dev 覆盖了公共配置)

中级深入

外部配置 vs 内部配置

# 外部配置(jar 包外,优先级高) # 1. jar 包同级目录的 config/ 子目录 # ./config/application.yml # 2. jar 包同级目录 # ./application.yml # 3. classpath 中的 config/ 包 # classpath:/config/application.yml # 4. classpath 根目录 # classpath:/application.yml # 优先级:1 > 2 > 3 > 4 # 外部 config/ > 外部根目录 > 内部 config/ > 内部根目录 # 运维场景:jar 包外放 application.yml # java -jar app.jar --spring.config.location=/etc/app/application.yml

命令行参数覆盖

# 命令行参数优先级最高 java -jar app.jar --server.port=9090 --app.name=test # 即使 application.yml 中配置了 server.port=8080 # 最终生效的是 9090 # 禁用命令行参数 SpringApplication app = new SpringApplication(App.class); app.setAddCommandLineProperties(false); app.run(args);

高级拓展

配置中心优先级

# Nacos 配置中心 + Spring Boot 配置优先级 # 1. Nacos 配置中心(shared-configs,共享配置) # 2. Nacos 配置中心(extension-configs,扩展配置) # 3. Nacos 配置中心(应用专属配置) # 4. bootstrap.yml # 5. application.yml # bootstrap.yml vs application.yml # bootstrap.yml:父上下文,最早加载,用于配置中心连接信息 # application.yml:子上下文,业务配置 # bootstrap.yml 示例 spring: application: name: user-service cloud: nacos: config: server-addr: localhost:8848 file-extension: yml # 配置中心配置覆盖本地配置 # Nacos 中的 user-service.yml 会覆盖本地的 application.yml

动态刷新配置

# @RefreshScope 实现配置热更新 @RestController @RefreshScope // 配置变更时重新创建 Bean public class ConfigController { @Value("${app.message:Hello}") private String message; @GetMapping("/message") public String getMessage() { return message; // Nacos 修改配置后自动更新 } } # 原理 # 1. Nacos 配置变更 → 发送 RefreshEvent # 2. @RefreshScope 的 Bean 被标记为 dirty # 3. 下次访问时重新创建 Bean,获取新配置

实战场景

场景:Docker 环境配置

# Docker 部署时通过环境变量覆盖配置 # docker-compose.yml services: app: image: my-app:latest environment: - SERVER_PORT=8080 - SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mydb - SPRING_DATASOURCE_USERNAME=root - SPRING_DATASOURCE_PASSWORD=secret ports: - "8080:8080" # 环境变量映射规则 # server.port → SERVER_PORT # spring.datasource.url → SPRING_DATASOURCE_URL # 点号 → 下划线,全大写

面试模拟

面试官:Spring Boot 配置加载优先级是怎样的?

你:命令行参数最高,其次是环境变量,然后是外部配置文件(jar 包外),最后是内部配置文件(jar 包内)。profile 特定配置覆盖通用配置。核心原则:越外部优先级越高,越具体优先级越高。

面试官:bootstrap.yml 和 application.yml 有什么区别?

你:bootstrap.yml 由父 ApplicationContext 加载,优先级更高,最早加载,通常用于配置中心连接信息(如 Nacos 地址)。application.yml 由子 ApplicationContext 加载,用于业务配置。Spring Cloud 配置中心的配置会覆盖 application.yml。