@Value因不支持松散绑定、类型校验和嵌套结构而常为空或报错;@ConfigurationProperties专为结构化配置设计,支持松散绑定、校验及集合映射;自定义YAML需用spring.config.import加载,@PropertySource不兼容YAML。
@Value 读取配置值时为什么总为空或报错
因为
默认不支持松散绑定(如
→
),也不校验类型,更不支持嵌套对象。它只做简单字符串占位符替换,遇到 YAML 中的层级结构、驼峰/中划线混用、或非 String 类型字段时,极易返回 null 或抛
。
必须用完整路径,且大小写、连字符严格匹配:
对应
,写成
就失败
无法直接注入 List/Map,要手动写 SpEL 表达式,比如
,但容易出语法错误
不支持 JSR-303 校验,哪怕加了
也无效
若配置项不存在,默认值必须是字符串字面量(
),不能是
或表达式
@ConfigurationProperties 绑定配置类的正确姿势
它专为结构化配置设计,能自动映射 YAML/Properties 的嵌套结构、处理松散绑定、支持校验和元数据提示。但前提是类必须被 Spring 容器管理,且启用配置绑定。
配置类需加
和
(或通过
显式注册)
字段名用标准 Java 驼峰命名,YAML 中可用
、
、
任意一种 —— 全部能绑定到
集合类型直接声明,例如
,YAML 写成
即可
加上
和字段级注解(如
)才能触发校验,否则校验不生效
application.yml 和自定义配置文件(如 app-dev.yml)怎么一起用
Spring Boot 默认只加载
。想读取自定义文件,得主动导入,且注意加载顺序和 profile 激活逻辑。
用
只支持 .properties,对 YAML 会报
—— 别这么干
正确方式是通过
(2.4+):在
里加
如果要用 profile 区分,把文件命名为
,启动时加
,无需额外配置
自定义文件中的配置,
和
都能读,但必须确保该文件已被 Spring Environment 加载(可通过
验证)
为什么 @ConfigurationProperties 的值有时没刷新,而 @Value 看起来“实时”
这不是“实时”,而是错觉。
在每次注入点被创建时重新求值(比如每次新建一个 prototype Bean),而
绑定是一次性的,在 Bean 初始化时完成。所谓“没刷新”,本质是没启用配置刷新机制。
要支持运行时更新,类必须实现
(加
),且项目引入 spring-cloud-context
本身不支持刷新;所谓“变”是因为你可能在 prototype Bean 里反复 new,每次 new 都触发新注入 —— 这不是热更新,是重建
生产环境慎用动态刷新,配置变更可能引发状态不一致;优先用重启 + 配置中心(如 Nacos/Apollo)
配置绑定不是选“哪个更高级”,而是看场景:单个字符串参数、临时调试用
;模块化、多环境、带校验的配置,必须用
。最容易被忽略的是:自定义 YAML 文件必须通过
加载,而不是靠
,后者对 YAML 天然不兼容。
@Valuemy-app.namemyApp.nameIllegalArgumentException@Value("${app.config.timeout}")app.config.timeout=3000appConfig.timeout@Value("#{${app.urls:[]}}")@NotBlank"default"null@ConfigurationProperties(prefix = "app")@Component@EnableConfigurationPropertiesapp.config-timeoutapp.configTimeoutAPP_CONFIG_TIMEOUTconfigTimeoutList urls; urls: [a.com, b.com]@Validated@Min(1)application.yml@PropertySource("classpath:app-dev.yml")IOExceptionspring.config.importapplication.ymlspring.config.import: optional:classpath:app-dev.ymlapplication-dev.yml--spring.profiles.active=dev@ConfigurationProperties@ValueEnvironment.getProperty("xxx")@Value@ConfigurationProperties@ConfigurationPropertiesRefreshScope@RefreshScope@Value@Value@ConfigurationPropertiesspring.config.import@PropertySource