SpringBoot 3.4.3 @ConfigurationProperties映射Map失败,@Value可正常使用
@ConfigurationProperties结合Map加载配置为空的解决方法
问题描述
使用@Value注解可正常获取配置,但结合Map与@ConfigurationProperties注解时,Map始终为空或null。相关配置与代码如下:
application.yml配置
endpoints: first-enpoint: host: it.api.com method: GET path: /v1/example/data another-endpoint: host: it.api.com method: POST path: /v2/example/data
配置类代码
@Component @ConfigurationProperties(prefix = "endpoints") @Data @Slf4j public class EndpointsProperties { private Map<String, Endpoint> endpoints; @PostConstruct public void init() { log.info("loaded endpoints from application.yml: {}", endpoints); } @Data public static class Endpoint { private String host; private String method; private String path; } }
启动日志
2025-03-21T16:43:39.524+01:00 INFO 25712 --- [middleware] [ main] c.s.m.c.httpclient.EndpointsProperties : loaded endpoints from application.yml: null
原因分析
核心问题是@ConfigurationProperties的prefix与Map字段名重复:
- 设置的
prefix = "endpoints"会让Spring从endpoints节点下加载配置 - 但Map字段名也是
endpoints,导致Spring尝试寻找endpoints.endpoints路径下的配置 - 而application.yml中
endpoints节点下直接是first-enpoint、another-endpoint这些子节点,不存在endpoints.endpoints路径,因此无法匹配,Map始终为null
解决方案
有两种可行的修改方式:
方案一:修改Map字段名,避免与prefix重复
保留prefix = "endpoints",将Map字段名改为非endpoints的名称,比如endpointMap:
@Component @ConfigurationProperties(prefix = "endpoints") @Data @Slf4j public class EndpointsProperties { private Map<String, Endpoint> endpointMap; @PostConstruct public void init() { log.info("loaded endpoints from application.yml: {}", endpointMap); } @Data public static class Endpoint { private String host; private String method; private String path; } }
这样Spring会自动将endpoints节点下的所有子节点映射到endpointMap中。
方案二:去掉prefix,让Map字段名对应根节点配置
移除@ConfigurationProperties的prefix参数,让Map字段名endpoints直接对应根节点的endpoints配置:
@Component @ConfigurationProperties @Data @Slf4j public class EndpointsProperties { private Map<String, Endpoint> endpoints; @PostConstruct public void init() { log.info("loaded endpoints from application.yml: {}", endpoints); } @Data public static class Endpoint { private String host; private String method; private String path; } }
额外注意事项
如果IDE没有配置自动提示,建议添加配置处理器依赖,避免拼写错误:
- Maven:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
- Gradle:
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
内容的提问来源于stack exchange,提问作者user2984483
相关产品推荐
相关产品推荐

