可以春天@Autowired地图?

Joe*_*Joe 29 java spring autowired

这是地图

@Autowired
private Map<String, ISendableConverter> converters;
Run Code Online (Sandbox Code Playgroud)

ISendableConverter

public interface ISendableConverter {

    ISendableMsg convert(BaseMessage baseMessage);

    String getType();
}
Run Code Online (Sandbox Code Playgroud)

有几个类实现 ISendableConverter

我想converters通过使用spring Autowried 将它们注入变量.

类的实例作为值,方法的结果@Autowried作为键.

像这个

@Component
public class SendableVoiceMsgConverter implements ISendableConverter {

    @Override
    public ISendableMsg convert(BaseMessage baseMessage) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getType() {
        return "VOICE";
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?如何?

Mar*_*szS 17

试试像@Resource这样的东西- 我还没有测试过这段代码.

@Resource(name="converters")
private Map<String, ISendableConverter> converters;
Run Code Online (Sandbox Code Playgroud)

要么

@Value("#{converters}")
private Map<String, ISendableConverter> converters;
Run Code Online (Sandbox Code Playgroud)

来自Spring Docs

(..)自身定义为集合或映射类型的bean不能通过@Autowired注入,因为类型匹配不适用于它们.对这样的bean 使用@Resource,通过唯一名称引用特定的集合或映射bean.

这应该有效,只有你准备这样的convertersbean:

<util:map id="converters" scope="prototype" map-class="java.util.HashMap" 
          key-type="java.lang.String" value-type="...ISendableConverter">
    <entry key="VOICE" value="sendableVoiceMsgConverter" />
</util:map>
Run Code Online (Sandbox Code Playgroud)

这也是类似的问题:


Tim*_*mYi 11

你可以这样做:

@SuppressWarnings("unused")
private List<OneTypeImageLoader> imageLoaders;
private Map<String, OneTypeImageLoader> imageLoaderMap=new HashMap<>();

@Autowired
public void setImageLoaders(List<OneTypeImageLoader> imageLoaders) {
    this.imageLoaders = imageLoaders;
    imageLoaders.forEach(l-> {
        imageLoaderMap.put(l.getType(), l);
    });
}
Run Code Online (Sandbox Code Playgroud)


Ond*_*zek 10

您可以使用Spring Java配置使用您选择的键自动创建初始化映射:

在带@Configuration注释的类中注释:

@Autowired
private List<ISendableConverter> sendableConverters;

@Bean
public Map<String, ISendableConverter> sendableConvertersMap() {
    Map<String, ISendableConverter> sendableConvertersMap = new HashMap<>();
    for (ISendableConverter converter : sendableConverters) {
        sendableConvertersMap.put(converter.getType(), converter);
    }
    return sendableConvertersMap;
}
Run Code Online (Sandbox Code Playgroud)

比你注入这张地图:

@Resource()
private Map<String, ISendableConverter> sendableConverters;
Run Code Online (Sandbox Code Playgroud)

@Resource如果已定义更多相同类型的地图,则可以选择将一些选择器字符串添加到注释中.

这样你所要做的就是ISendableConverter用你的spring bean 实现它,它将自动出现在上面定义的Map中.您无需为每个实现手动创建地图项.


Ser*_*hyr 8

尝试这样的东西,它适合我

private Map<String, ISendableConverter> converters;

@Autowired
public void setUploadServices(Set<ISendableConverter> converters){
    this.conveters = converters.stream()
        .collect(Collectors.toMap(ISendableConverter::getType, Function.identity()));
}
Run Code Online (Sandbox Code Playgroud)

使用构造函数注入可以实现相同的结果:

private Map<String, ISendableConverter> converters;

@Autowired
public Foo(Set<ISendableConverter> converters) {
    this.conveters = converters.stream()
        .collect(Collectors.toMap(ISendableConverter::getType, Function.identity()));
}
Run Code Online (Sandbox Code Playgroud)