我需要用来自的值填充pojo application.yml
动态地,因为前缀是在运行时计算的。
我阅读了spring的源代码,发现它使用 org.springframework.boot.context.properties.bind.Binder
类来用给定前缀的属性填充给定类型的pojo。壮观的!
不过,下面的代码引发了一个异常:
// my custom prefix has CamelCase style, but I've found that props
// are case insensitive and I simply can lowercase it to make it valid
var configProp = ConfigurationPropertyName.ofIfValid(pojoPropPrefix.toLowerCase());
var pojos = binder.bindOrCreate(
configProp,
Bindable.listOf(Pojo.class),
null);
引发的异常(最深的原因):
Caused by: org.springframework.boot.context.properties.source.InvalidConfigurationPropertyNameException: Configuration property name 'this$0' is not valid
at org.springframework.boot.context.properties.source.ConfigurationPropertyName.elementsOf(ConfigurationPropertyName.java:577)
at org.springframework.boot.context.properties.source.ConfigurationPropertyName.probablySingleElementOf(ConfigurationPropertyName.java:550)
at org.springframework.boot.context.properties.source.ConfigurationPropertyName.append(ConfigurationPropertyName.java:207)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:447)
at org.springframework.boot.context.properties.bind.ValueObjectBinder$ConstructorParameter.bind(ValueObjectBinder.java:290)
at org.springframework.boot.context.properties.bind.ValueObjectBinder.bind(ValueObjectBinder.java:71)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:451)
at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:571)
at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:557)
at org.springframework.boot.context.properties.bind.Binder$Context.access$300(Binder.java:512)
at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:449)
at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:390)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:319)
... 45 more
这个 Binder
试图绑定 my.prefix.PojoList[0]
不知怎的试图填补 0
属性而不是填充列表。
我找到了解决办法-把道具绑在 LinkedHashMap
相反
var responses = binder.bindOrCreate(
configProp,
// does not work, tries to instantiate interface Map
// Bindable.mapOf(String.class, ResponsesElement.class),
Bindable.of(ResolvableType.forType(new ParameterizedTypeReference<LinkedHashMap<String, Object>>() {})),
null);
但是上面的代码只适用于 LinkedHashMap<String,
Object >
(生成嵌套贴图),而不是 Pojo
.
如果我使用 LinkedHashMap<String, Pojo>
,它仍抛出“配置属性名称'this$0'is not valid”异常。
也许有人有想法,为什么会提出这个例外,是否有机会填充 Pojo
列表?
升级版
我已经找到了解决办法 LinkedHashMap<String, Object>
,它只是使用 ObjectMapper#convert
在上面。
但我想一定有更优雅的解决办法 ObjectMapper
事物只允许从 Map<String, Object>
至 Map<String, Pojo>
因为 String
源Map键( "0"
, "1"
等等)。
转换自 Map<String, Object>
至 List<Pojo>
直接还是不可能的。
最初的问题是 Binder
.
暂无答案!
目前还没有任何答案,快来回答吧!