You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.7:ConfigurationProperties映射Map<String, Integer>失败求助

Spring Boot 2.7.7配置映射Map<String, Integer>为空的问题排查

问题根源

  1. 配置路径不匹配
    你的@ConfigurationProperties前缀设为limiter.settings,但类里的字段名又是settings,这会让Spring尝试绑定limiter.settings.settings路径下的配置,而你的yml配置是直接挂在limiter.settings节点下的a、b,根本不存在settings子节点,自然映射不到内容,得到空Map。

  2. final字段与构造方法的冲突
    字段用了final修饰,还只加了@AllArgsConstructor,没有提供无参构造。Spring Boot默认的配置绑定逻辑需要无参构造实例化对象,再通过Setter注入属性,但final字段的Setter是无效的(无法修改final变量);如果想用构造绑定,还缺少@ConstructorBinding注解配合,导致无法正确注入Map。

  3. 注解混用导致逻辑混乱
    同时使用@Component和@EnableConfigurationProperties,前者会把类当作普通Bean注册,后者是专门处理配置属性Bean的机制,两者混用可能让Spring的Bean处理逻辑冲突,影响配置绑定效果。


解决办法

方案一:调整前缀+使用Setter注入(简单直观)

修改配置类,让路径匹配,去掉final字段和全参构造:

@Component
@ConfigurationProperties(prefix = "limiter")
@Getter
@Setter
public class LimiterSettings {
    private Map<String, Integer> settings;
}
  • 前缀改为limiter,这样settings字段就对应yml里的limiter.settings节点,直接映射下面的a、b键值对。
  • 去掉final和@AllArgsConstructor,Lombok的@Getter@Setter会自动生成无参构造,Spring可以通过Setter完成属性注入。

方案二:构造绑定(适合不可变对象场景)

如果需要保留final字段,用构造绑定方式:

@ConfigurationProperties(prefix = "limiter")
@ConstructorBinding
@Getter
public class LimiterSettings {
    private final Map<String, Integer> settings;

    public LimiterSettings(Map<String, Integer> settings) {
        this.settings = settings;
    }
}
  • 加上@ConstructorBinding告诉Spring用构造方法注入配置属性。
  • 移除类上的@Component,在启动类或者任意配置类上添加@EnableConfigurationProperties(LimiterSettings.class),由该注解负责注册配置属性Bean。

使用验证

两种方案下,直接在LimiterService中注入即可:

public class LimiterService implements ILimiterService {
    private final LimiterSettings limiterSettings;

    @Autowired
    public LimiterService(LimiterSettings limiterSettings) {
        this.limiterSettings = limiterSettings;
    }
}

内容的提问来源于stack exchange,提问作者littleAlien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:17:39