Spring Boot外部化配置深度解析
Spring Boot外部化配置深度解析引言外部化配置是Spring Boot的核心特性之一允许将应用配置与代码分离使得同一个应用可以在不同环境开发、测试、生产使用不同的配置。Spring Boot提供了多层次的配置加载机制从多个来源按优先级加载配置实现配置的灵活管理。一、配置源优先级1.1 配置加载顺序Spring Boot按照以下顺序加载配置高优先级覆盖低优先级命令行参数系统环境变量应用程序属性application.yml等RandomValuePropertySourceprofile-specific配置文件打包在JAR中的默认配置。1.2 配置属性源// 获取所有配置属性源 Autowired private ConfigurableEnvironment environment; public void listPropertySources() { for (PropertySource? source : environment.getPropertySources()) { System.out.println(source.getName() : source.getSource()); } }二、配置文件详解2.1 多环境配置# application.yml - 默认配置 spring: application: name: myapp profiles: active: dev # application-dev.yml - 开发环境 spring: datasource: url: jdbc:mysql://localhost:3306/dev_db username: dev_user password: dev_pass # application-prod.yml - 生产环境 spring: datasource: url: jdbc:mysql://prod-db:3306/prod_db username: prod_user password: ${DB_PASSWORD} # application-test.yml - 测试环境 spring: datasource: url: jdbc:h2:mem:testdb2.2 YAML配置# 复杂结构配置 server: port: 8080 servlet: context-path: /api session: timeout: 30m spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 myapp: cache: caffeine: spec: maximumSize1000,expireAfterWrite10m retry: max-attempts: 3 backoff: initial-interval: 1000 multiplier: 2.0 max-interval: 10000三、配置绑定3.1 ConfigurationPropertiesConfigurationProperties(prefix myapp.service) public class ServiceProperties { private String baseUrl; private int timeout 5000; private boolean enabled true; private ListString allowedOrigins new ArrayList(); private MapString, String headers new HashMap(); public String getBaseUrl() { return baseUrl; } public void setBaseUrl(String baseUrl) { this.baseUrl baseUrl; } // getters and setters } Configuration EnableConfigurationProperties(ServiceProperties.class) public class ServiceConfig { }3.2 松散绑定// application.yml中可以使用以下格式 myapp: service: base-url: http://localhost # 绑定到 baseUrl timeout-ms: 5000 # 绑定到 timeout enabled-flag: true # 绑定到 enabled3.3 数据校验ConfigurationProperties(prefix myapp.service) Validated public class ServiceProperties { NotBlank private String baseUrl; Min(1000) Max(60000) private int timeout 5000; Pattern(regexp \\d\\.\\d\\.\\d\\.\\d) private String ipAddress; Email private String adminEmail; }四、环境变量和系统属性4.1 环境变量配置# Linux/Mac export SPRING_DATASOURCE_URLjdbc:mysql://localhost:3306/mydb export SPRING_DATASOURCE_USERNAMEroot export SPRING_DATASOURCE_PASSWORDsecret # Windows set SPRING_DATASOURCE_URLjdbc:mysql://localhost:3306/mydb4.2 命令行参数java -jar app.jar --spring.profiles.activeprod \ --server.port8443 \ --myapp.service.base-urlhttp://api.example.com4.3 随机值配置# 生成随机值 myapp: secret: ${random.uuid} number: ${random.int} long-number: ${random.long} port: ${random.int[1024,65536]} value: ${random.value}五、配置加密5.1 Jasypt集成dependency groupIdcom.github.ulisesbocchio/groupId artifactIdjasypt-spring-boot-starter/artifactId version3.0.5/version /dependency# 配置文件 jasypt: encryptor: algorithm: PBEWithMD5AndDES password: ${JASYPT_PASSWORD} iv-generator-classname: org.jasypt.iv.RandomIvGenerator myapp: database: password: ENC(加密后的密文)// 加密工具类 Service public class PasswordEncryptService { private final StringEncryptor stringEncryptor; public StringEncryptService(StringEncryptor stringEncryptor) { this.stringEncryptor stringEncryptor; } public String encrypt(String plainText) { return stringEncryptor.encrypt(plainText); } public String decrypt(String encryptedText) { return stringEncryptor.decrypt(encryptedText); } }5.2 敏感配置外部化# 启动时指定加密密钥 java -Djasypt.encryptor.passwordmySecretPassword \ -jar app.jar六、配置导入6.1 Spring Boot 2.4导入# 从外部文件导入配置 spring: config: import: optional:file:./config.yaml import: optional:classpath:defaults.properties6.2 Profile条件导入spring: config: import: - optional:classpath:application-common.yml - optional:classpath:application-${spring.profiles.active}.yml七、配置刷新7.1 Spring Cloud配置刷新dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-config/artifactId /dependencymanagement: endpoints: web: exposure: include: refresh,health,infoRefreshScope ConfigurationProperties(prefix myapp.service) public class ServiceProperties { // 配置更新后会自动刷新 }7.2 配置监听Component public class ConfigChangeListener { EventListener public void onApplicationEvent( EnvironmentChangeEvent event) { for (String key : event.getKeys()) { System.out.println(配置变更: key environment.getProperty(key)); } } }八、最佳实践8.1 配置组织resources/ ├── application.yml # 公共配置 ├── application-dev.yml # 开发环境 ├── application-test.yml # 测试环境 ├── application-prod.yml # 生产环境 └── application-local.yml # 本地覆盖8.2 配置分层# application.yml spring: application: name: myapp profiles: active: ${SPRING_PROFILES_ACTIVE:dev} # 公共配置 myapp: version: 1.0.0 description: My Application # 环境特定配置在对应文件中总结Spring Boot的外部化配置机制提供了极大的灵活性通过合理使用配置属性、环境变量、profile等手段可以实现配置的集中管理和环境差异化。配置加密、导入、刷新等高级特性进一步增强了配置管理的安全性和可维护性。