使用 @ConfigurationPropertiesBinding 的转换器不适用于复杂的源类型(列表、地图等)

Тем*_*оже 6 spring spring-boot

我需要从 application.yml 中的数组透明转换为应用程序中的特定类型。我想要 use
@ConfigurationPropertiesBinding,但转换器 ( SimpleConverter) 只适用于简单的源类型。为什么 Analog ( ComplexConverter) 不适用于复杂源类型?

独立示例:

package com.example;


import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.util.List;

@SpringBootTest
@SpringBootConfiguration
@ComponentScan("com.example")
@EnableConfigurationProperties(ConfBean.class)
public class ComplexConverterTest {

    @Autowired
    private ConfBean confBean;

    @Test
    public void test() {
        Assertions.assertEquals(2 * 2, confBean.getSimple().getPowValue()); //work

        //after I take NullPointer
        Assertions.assertEquals(2, confBean.getComplex().getLeft());
        Assertions.assertEquals(3, confBean.getComplex().getLeft());
    }

}

class SimpleVal {
    private final int powValue;

    SimpleVal(int powValue) {
        this.powValue = powValue;
    }

    public int getPowValue() {
        return powValue;
    }
}

@Component
@ConfigurationPropertiesBinding
class SimpleConverter implements Converter<Integer, SimpleVal> {

    @Override
    public SimpleVal convert(Integer source) {
        return new SimpleVal(source * source);
    }
}


@Component
@ConfigurationPropertiesBinding
class ComplexConverter implements Converter<List<Integer>, ComplexVal> {

    @Override
    public ComplexVal convert(List<Integer> source) {
        return new ComplexVal(source.get(0), source.get(1));
    }
}

class ComplexVal {
    private final int left;
    private final int right;

    ComplexVal(int left, int right) {
        this.left = left;
        this.right = right;
    }

    public int getLeft() {
        return left;
    }

    public int getRight() {
        return right;
    }
}

@ConfigurationProperties("conf")
class ConfBean {
    private SimpleVal simple;
    private ComplexVal complex;

    public SimpleVal getSimple() {
        return simple;
    }

    public void setSimple(SimpleVal simple) {
        this.simple = simple;
    }

    public ComplexVal getComplex() {
        return complex;
    }

    public void setComplex(ComplexVal complex) {
        this.complex = complex;
    }
}

Run Code Online (Sandbox Code Playgroud)

它是可编译/可执行的。

我的应用程序.yaml

conf:
  simple: 2
  complex: [ 2, 3 ]
Run Code Online (Sandbox Code Playgroud)

感谢您的关注。