简体   繁体   English

如何将yml对象绑定到声明为该对象实现的接口的字段?

[英]How to bind a yml object to a field declared as an interface that the object implements?

I have this java hierarchy: 我有这个Java层次结构:

interface Foo {
    // methods
}

@Data
@Component
@NoArgsConstructor
class Bar implements Foo {
    // override interface methods
}

@Data
@Component
@NoArgsConstructor
class Baz implements Foo {
    // override interface methods
}

@Data
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "foo")
class FooConfig {
    List<Foo> stuff = new Arraylist<>;
}

and this application.yml 和这个application.yml

foo:
    stuff[0]: { Bar }
    stuff[1]: { Baz }

But this does not work. 但这是行不通的。 I get this exception 我得到这个例外

Failed to instantiate [Foo]: Specified class is an interface 无法实例化[Foo]:指定的类是接口

When i change List<Foo> stuff to List<Bar> stuff it only works for stuff[0]: { Bar } 当我将List<Foo> stuff更改为List<Bar> stuff它仅适用于stuff[0]: { Bar }

You don't need any configuration properties/yml files to achieve this. 您不需要任何配置属性/ yml文件即可实现此目的。 Spring is intelligent enough to detect implementations of an interface. Spring足够智能,可以检测接口的实现。

Just do this. 就是这样

@Data
@Configuration
class FooConfig {
    @Autowired
    List<Foo> stuff;
}

Spring will automagically search all the implementations of interface Foo and autowire it. Spring将自动搜索接口Foo所有实现,并将其自动连线。

NOTE: All the implementations should be a bean(in your case you have @Component on both Bar and Baz, so it should be fine) 注意:所有实现都应该是一个bean(在您的情况下,Bar和Baz上都具有@Component ,因此应该没问题)

You can even do 你甚至可以做

@Data
@Configuration
class FooConfig {
   @Autowired
   Map<String, Foo> stuffMap;
}

In this case, spring will create a map, with key as bean names(by default it will be bar and baz) 在这种情况下,spring将创建一个映射,键为Bean名称(默认情况下为bar和baz)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM