使用Spring Boot和application.yml注入Map <string,double =“”>

时间:2017-05-10 09:52:43

标签: java spring spring-boot properties

我知道,有许多问题在SO中提出类似的问题,但我无法使用它们摆脱这种情况。

我有一个Spring Boot应用程序。

@SpringBootApplication
@EnableConfigurationProperties
public class Application implements ApplicationRunner {
    public static void main(String[] args) {
        SpringApplication.run(Application .class, args);
    }
}

然后我有以下课程。

@Component
@ConfigurationProperties(prefix = "somePrefix")
public class AClass {
    private final AnotherClass anotherClass;
    private final Map<String, Double> aMap;

    @Autowired
    public AffinityChecks(AnotherClass anotherClass,
                          Map<String, Double> aMap) {
        this.anotherClass = anotherClass;
        this.aMap = aMap;
    }

    // Omissis

最后,我有以下application.yml配置文件。

somePrefix:
  aMap:
    key1: 0.6
    key2: 0.2
    key3: 0.2

我想要的只是Spring在构建过程中将地图注入到AClass类型的对象中。我得到的错误如下。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.Map<java.lang.String, java.lang.Double>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

到底是怎么回事?

提前致谢。

1 个答案:

答案 0 :(得分:1)

Spring Boot不支持绑定到环境的元素的构造函数注入。你当然可以通常的方式注入实际的豆类。

您需要将要绑定的每个属性定义为常规Javabean属性(即使用getter / setter)。此规则有一个例外:地图和非标量值(即嵌套内容)只需要一个getter。

具体地说,如果AnotherClass是一个bean而FooClass是一些具有嵌套属性的pojo。

@Component
@ConfigurationProperties(prefix = "somePrefix")
public class AClass {
    private final AnotherClass anotherClass;
    private final Map<String, Double> aMap = new HashMap<>();
    private final FooClass foo = new FooClass();

    public AClass(AnotherClass anotherClass) { ...}

    public Map<String, Double> getaMap() { ... }

    public FooClass getFoo() { ... }

}

(请注意,getter是推断属性名称的东西。在上面的示例中,如果somePrefix.foo.xyz上有getXyz(),则可以映射FooClass

有一个示例in the documentation,其中包含其他详细信息。

(一个很好的暗示,你的代码是错的,因为地图不是bean,所以@Autowiring不是你试图实现的正确语义。