spring-boot-configurationproperties动态绑定-对象列表

mbzjlibv  于 2021-06-30  发布在  Java
关注(0)|答案(0)|浏览(683)

我需要用来自的值填充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 .

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题