Spring Boot如何通过@ConfigurationProperties映射Month与MonthDay的Map?
解决Spring配置属性绑定中EnumMap<Month, MonthDay>的解析问题
问题根源是Spring默认的MonthDay转换器不支持02-JAN这种dd-MMM格式的字符串解析,需要自定义转换器适配配置格式。
步骤1:自定义属性转换器
实现Converter<String, MonthDay>接口,指定匹配配置的日期格式,并通过@ConfigurationPropertiesBinding注解标记该转换器专门用于配置属性绑定:
import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import java.time.MonthDay; import java.time.format.DateTimeFormatter; import java.util.Locale; @Component @ConfigurationPropertiesBinding public class StringToMonthDayConverter implements Converter<String, MonthDay> { // 指定匹配配置的格式,Locale.ENGLISH确保英文月份缩写能被解析 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd-MMM", Locale.ENGLISH); @Override public MonthDay convert(String source) { return MonthDay.parse(source.trim(), FORMATTER); } }
步骤2:确保配置类的正确性
检查ConfigProps类的访问权限和注解配置,确保Spring能正确识别并绑定属性:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.time.Month; import java.time.MonthDay; import java.util.EnumMap; @Component @ConfigurationProperties(prefix = "") // 如果daysMap是yml根节点则留空,否则填对应前缀 public class ConfigProps { private EnumMap<Month, MonthDay> daysMap = new EnumMap<>(Month.class); // 必须提供getter/setter供Spring绑定属性 public EnumMap<Month, MonthDay> getDaysMap() { return daysMap; } public void setDaysMap(EnumMap<Month, MonthDay> daysMap) { this.daysMap = daysMap; } }
步骤3:保留原yml配置
你的application.yml配置无需修改,保持原有格式即可:
daysMap: JANUARY: 02-JAN MARCH: 15-DEC
注意事项
- 如果使用较旧版本的Spring Boot,
@ConfigurationPropertiesBinding注解可能不存在,此时可以通过配置类注册转换器Bean:import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import java.time.MonthDay; import java.time.format.DateTimeFormatter; import java.util.Locale; @Configuration public class ConversionConfig { @Bean public Converter<String, MonthDay> stringToMonthDayConverter() { return source -> MonthDay.parse(source.trim(), DateTimeFormatter.ofPattern("dd-MMM", Locale.ENGLISH)); } } - 必须指定
Locale.ENGLISH,避免系统默认语言非英文时,无法解析JAN这类英文月份缩写。
内容的提问来源于stack exchange,提问作者IceMajor
相关产品推荐
相关产品推荐

