通常,Spring通过@ConfigurationProperties和转换器将属性映射到POJO方面做得很出色。
在更复杂的情况下,我需要有序地图,所以我有
TreeMap<Instant, Integer> variable = new TreeMap<>();
几乎可行:调试器显示在调用PostConstruct方法时,正确转换了属性,并使用期望值初始化了变量。
此后,ConfigurationPropertiesBindingPostProcessor立即无法按照以下堆栈跟踪尝试在TreeMap中查找类型为String的键:
java.lang.ClassCastException: java.time.Instant cannot be cast to java.lang.String
at java.lang.String.compareTo(String.java:111)
at java.util.TreeMap.getEntry(TreeMap.java:352)
at java.util.TreeMap.get(TreeMap.java:278)
at org.springframework.boot.bind.RelaxedDataBinder.isBlanked(RelaxedDataBinder.java:328)
at org.springframework.boot.bind.RelaxedDataBinder.initializePath(RelaxedDataBinder.java:283)
at org.springframework.boot.bind.RelaxedDataBinder.normalizePath(RelaxedDataBinder.java:259)
at org.springframework.boot.bind.RelaxedDataBinder.modifyProperty(RelaxedDataBinder.java:240)
at org.springframework.boot.bind.RelaxedDataBinder.modifyProperties(RelaxedDataBinder.java:155)
at org.springframework.boot.bind.RelaxedDataBinder.doBind(RelaxedDataBinder.java:128)
at org.springframework.validation.DataBinder.bind(DataBinder.java:740)
at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:272)
at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:240)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:330)
... 21 common frames omitted
Wrapped by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...': Could not bind properties to ... (prefix=..., ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is java.lang.ClassCastException: java.time.Instant cannot be cast to java.lang.String
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:335)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:292)
at org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.rebind(ConfigurationPropertiesRebinder.java:105)
at org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.rebind(ConfigurationPropertiesRebinder.java:90)
at org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.onApplicationEvent(ConfigurationPropertiesRebinder.java:138)
at org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.onApplicationEvent(ConfigurationPropertiesRebinder.java:51)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration.afterSingletonsInstantiated(ConfigurationPropertiesRebinderAutoConfiguration.java:79)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:781)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
...
如果Map类型不是TreeMap或键是String,那么这当然可能不会重现。
在我看来,这似乎是个错误。有更深刻理解的人可以确认吗?