多环境配置与外部化配置
多环境配置与外部化配置
Spring Boot 的配置体系极为灵活,支持多环境切换、外部化配置、强类型绑定等多种特性。掌握这些配置技巧,能让你的应用在不同环境间零改动切换,同时保证敏感信息的安全。
多环境配置
application-{profile}.yml
Spring Boot 通过 Profile 机制支持多环境配置。只需创建以 application-\{profile\}.yml 命名的文件:
src/main/resources/
├── application.yml # 公共配置(所有环境共享)
├── application-dev.yml # 开发环境
├── application-test.yml # 测试环境
├── application-prod.yml # 生产环境
└── application-local.yml # 本地个性化配置激活 Profile
# 方式1:启动参数
java -jar app.jar --spring.profiles.active=prod
# 方式2:环境变量(OS 环境变量优先级更高)
export SPRING_PROFILES_ACTIVE=prod
# 方式3:JVM 参数
java -Dspring.profiles.active=prod -jar app.jar
# 方式4:application.yml 中设置(不推荐,会被启动参数覆盖)
spring:
profiles:
active: prod配置优先级
Spring Boot 的配置按优先级从高到低排序(高优先级覆盖低优先级):
- 命令行参数
--spring.profiles.active=prod - OS 环境变量
SPRING_PROFILES_ACTIVE=prod - application-{profile}.yml(带 profile 的配置文件)
- application.yml(不带 profile 的默认配置)
- @PropertySource 或
@TestPropertySource注解加载的配置文件
配置示例
# application.yml — 公共配置
spring:
application:
name: blog-api
datasource:
url: jdbc:mysql://localhost:3306/blog
# application-dev.yml — 开发环境
spring:
datasource:
url: jdbc:mysql://localhost:3306/blog_dev
h2:
console:
enabled: true
jpa:
show-sql: true
logging:
level:
com.example: DEBUG
org.hibernate.SQL: DEBUG
# application-prod.yml — 生产环境
spring:
datasource:
url: jdbc:mysql://prod-db.example.com:3306/blog
jpa:
show-sql: false
logging:
level:
com.example: INFO
file:
name: /var/log/blog/application.log@ConfigurationProperties 强类型配置绑定
@ConfigurationProperties 是将外部配置绑定到 POJO 的首选方式,相比 @Value 更具类型安全和代码可读性。
基本用法
// 配置属性类
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String version;
private int maxConnections = 100;
private List<String> allowedOrigins = new ArrayList<>();
private Map<String, String> metadata = new HashMap<>();
// 支持嵌套配置对象
private Email email = new Email();
private Retry retry = new Retry();
// getters and setters(必须有,或使用 Lombok @Data)
public static class Email {
private String host = "smtp.example.com";
private int port = 587;
private String username;
private String password;
// getters and setters
}
public static class Retry {
private int maxAttempts = 3;
private long delayMs = 1000;
// getters and setters
}
}# application.yml
app:
name: blog-api
max-connections: 200
allowed-origins:
- "http://localhost:3000"
- "http://dev.example.com"
metadata:
team: backend
owner: alice
email:
host: smtp.gmail.com
port: 587
username: noreply@example.com
password: ${SMTP_PASSWORD} # 引用环境变量
retry:
max-attempts: 5
delay-ms: 2000注册为 Bean
// 方式1:@EnableConfigurationProperties(推荐,精确控制启用时机)
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig {
// ...
}
// 方式2:@Component(自动注册为 Bean)
@Component
@ConfigurationProperties(prefix = "app")
@Validated // 启用配置校验
public class AppProperties {
// ...
}启动类上的快捷方式
@SpringBootApplication
@ConfigurationPropertiesScan // Spring Boot 2.2+ 新增,扫描 @ConfigurationProperties 类
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}@Value 占位符
@Value 适合注入单个配置值,不适合绑定复杂结构:
@Service
public class NotificationService {
// 注入简单值
@Value("${app.email.host}")
private String smtpHost;
@Value("${app.email.port:587}") // 支持默认值
private int smtpPort;
@Value("${app.retry.max-attempts:3}")
private int maxRetries;
// 注入环境变量
@Value("${HOME:/tmp}")
private String homeDir;
@Value("${spring.application.name}")
private String appName;
// SpEL 表达式
@Value("#{systemProperties['user.timezone'] ?: 'Asia/Shanghai'}")
private String timezone;
// 注入列表(需要借助 SpEL)
@Value("#{'${app.allowed-origins}'.split(',')}")
private List<String> allowedOrigins;
// ❌ @Value 不支持复杂对象绑定
// ✅ 应该使用 @ConfigurationProperties
}配置校验
@Validated + @Constraint
@Component
@ConfigurationProperties(prefix = "app")
@Validated // 开启校验
public class AppProperties {
@NotBlank
@Pattern(regexp = "^[a-z][a-z0-9-]*$")
private String name;
@Min(1)
@Max(65535)
private int port;
@Email
private String adminEmail;
@NestedConfigurationProperty // 嵌套对象也要校验
private Email email = new Email();
}启用后,若配置不合法,Spring Boot 启动时会抛出 BindException 并列出所有错误:
Binding to target org.springframework.boot.context.properties.bind.BindException: ... failed:
Property: app.port
Value: 99999
Reason: 必须介于 1 到 65535 之间敏感信息加密
jasypt-spring-boot(社区方案)
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency># 使用 ENC() 包裹加密值
spring:
datasource:
password: ENC(abc123DEF456/xxx==) # AES 加密后的密文
jasypt:
encryptor:
password: ${JASYPT_PASSWORD} # 脱敏:密码来自环境变量
algorithm: PBEWithMD5AndDES加密时使用命令行工具生成密文:
# Maven 插件方式
./mvnw jasypt:encrypt -Djasypt.encryptor.password=mySecret
# 命令行方式
java -cp jasypt-*.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \
input=myPassword algorithm=PBEWithMD5AndDES password=mySecret配置加载顺序
Spring Boot 配置文件加载顺序(后面的覆盖前面的):
1. classpath:/application.yml
2. classpath:/application-{profile}.yml
3. file:./config/application.yml(项目根目录 config 子目录)
4. file:./application.yml(项目根目录)
5. classpath:/application-local.yml(本地覆盖)
6. OS 环境变量
7. 命令行参数最佳实践:将
application.yml提交到版本控制,仅在本地创建application-local.yml覆盖个性化设置(如本地数据库密码),并在.gitignore中排除*-local.yml。
运行时动态配置刷新
Spring Boot 3.x 支持可选配置,在运行时重新绑定配置值:
@ConfigurationProperties(prefix = "app.feature")
@RefreshScope // Spring Cloud 注解:重新创建 Bean 并绑定新配置
public class FeatureProperties {
private boolean darkMode = false;
private List<String> enabledModules = new ArrayList<>();
// getters and setters
}当通过 Spring Cloud Config Server 或 Actuator 端点修改配置后,带 @RefreshScope 的 Bean 会重新创建并读取新值。
小结
- 多环境通过
application-\{profile\}.yml实现,激活方式是--spring.profiles.active=xxx @ConfigurationProperties是强类型配置绑定的首选方式,配合@Validated可实现配置校验@Value适合单个简单值注入,支持默认值和 SpEL 表达式- 敏感信息通过环境变量 +
${VAR}占位符方式注入,避免明文写在配置文件中 - Spring Boot 3.x 支持
ConfigurationPropertiesScan注解,自动扫描配置属性类
评论
Written by
AI-Writer
Related Articles
Spring Boot 自动配置原理
深入理解 @SpringBootApplication 注解组合、自动配置生效机制(spring.factories 与 AutoConfiguration.imports)、自定义 Starter 的编写方法
Read MoreSpring Security 安全认证
Spring Security 6.x 核心架构、认证与授权概念、基于 JWT 的无状态登录实现、OAuth 2.0 资源服务器入门、@PreAuthorize 方法级安全注解
Read More多环境配置与外部化配置
application-{profile}.yml 多环境切换、@ConfigurationProperties 强类型配置绑定、@Value 占位符、配置加密与自定义配置加载顺序
Read More