春天能@Autowired地图吗?

2022-08-31 22:27:14

这是地图

@Autowired
private Map<String, ISendableConverter> converters;

ISendableConverter

public interface ISendableConverter {

    ISendableMsg convert(BaseMessage baseMessage);

    String getType();
}

有一些类可以实现ISendableConverter

我想通过使用弹簧注释将它们注入到变量中。converters@Autowried

class 的实例作为值,方法的结果作为键。getType()

像这个

@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";
    }
}

这可能吗?以及如何?


答案 1

尝试使用类似@Resource - 我还没有测试过这个代码。

@Resource(name="converters")
private Map<String, ISendableConverter> converters;

@Value("#{converters}")
private Map<String, ISendableConverter> converters;

来自 春季文档

(..)本身定义为集合或映射类型的 Bean 无法通过@Autowired注入,因为类型匹配不能正确应用于它们。对此类豆子使用@Resource,通过唯一名称引用特定集合或映射豆。

这应该有效,只有当你像这样准备bean时:converters

<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>

这也是类似的问题:


答案 2

您可以使用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;
}

比你注入这个地图:

@Resource()
private Map<String, ISendableConverter> sendableConverters;

如果定义了更多相同类型的映射,则可以选择向注记中添加一些选择器字符串。@Resource

这样,您所要做的就是由您的弹簧豆实现,它将自动出现在上面定义的Map中。您无需为每个实现手动创建映射项。ISendableConverter


推荐