如何在 Spring Boot 中定义和读取自定义配置?
- 标签:Spring Boot、后端
🏛 业务架构师
在 Spring Boot 中定义自定义配置的推荐方式是类型安全的属性绑定(@ConfigurationProperties):
yaml
pay:
channel:
url: https://api.pay.com
timeout: 3000
retries: 2java
@Validated
@ConfigurationProperties(prefix = "pay.channel")
public record PayProperties(
@NotBlank String url,
@Min(100) long timeout,
int retries) { }读取侧:构造器直接注入 PayProperties(推荐,也可 @EnableConfigurationProperties 注册)。
对比零散的 @Value("${pay.channel.url}"),我的架构立场很明确:
- 成组配置必须结构化:十几个配置项散在各处
@Value,改名和排查是灾难;Properties 类有 IDE 导航、编译期类型检查、启动即校验(校验失败 fail-fast,不会带病运行); - 配置即业务文档:一个 Properties 类就是这个模块的"参数面板",新人接手成本骤降;
- 配置分层管理:默认值放 yml → 环境差异走环境变量/K8s ConfigMap → 运行时动态项走 Nacos(配合 @RefreshScope,注意 Bean 重建的语义);
- 敏感信息不进配置文件:密钥走 K8s Secret/Vault,注入环境变量。
一句话:@Value 管零散取值,@ConfigurationProperties 管模块配置资产——配置怎么管理,反映的是团队对"变更频率与风险"的认知。
🏗 系统架构师
定义:
yaml
pay:
app-id: 10001
timeout-ms: 3000读取两种:
@Value("${pay.app-id}"):单点读取,适合零散标量;@ConfigurationProperties(prefix = "pay")(推荐):类型安全整组绑定,支持构造器绑定、嵌套对象、Duration 与集合;配@Validated(@NotBlank、@Min)启动期校验——缺配置直接启动失败,fail-fast 是生产刚需。
架构治理:
- 配置按业务域聚合成 Properties 类,一域一类,配置清单一目了然;
- 补 additional-spring-configuration-metadata 文件,IDE 提示加默认值文档化;
- 动态刷新:两者都是启动期绑定,运行期变更需配置中心(Nacos 的
@RefreshScope)或重启。我倾向「可重启的配置就重启」(不可变、可追溯),只有开关类配置走动态推送; - 密钥类配置绝不进 Git,Vault/KMS 注入。
💻 全栈开发专家
定义 → 声明 → 使用三步,两种主流方式:
1. @Value 散装读取(单点取值):
java
@Value("${sms.app-id}")
private String appId;2. @ConfigurationProperties 结构化绑定(推荐):
java
@Component
@ConfigurationProperties(prefix = "sms")
@Validated
public class SmsProperties {
@NotBlank private String appId; // 校验失败直接拒绝启动
@Min(100) private int timeout = 3000;
private boolean enabled = true;
// getter/setter
}yaml
sms:
app-id: ax1001
timeout: 5000进阶用法:
- record 构造器绑定(Boot 3):
@ConfigurationProperties(prefix = "sms") public record SmsProperties(String appId, int timeout) {},不可变更干净 - 嵌套对象、
Map<String, Channel>直接映射多渠道配置 - 第三方场景用
@EnableConfigurationProperties(SmsProperties.class)
选择标准:相关配置超过 3 个必用 CP(类型安全、可校验、集中管理、IDE 补全);@Value 留给单点 + SpEL 动态计算。配置动态刷新:接 Nacos 后 @RefreshScope 让 Bean 在配置变更时重建。