1

我正在尝试一个看起来应该可以正常工作的非常简单的事情,但是我遇到了一些奇怪的行为:

应用程序上下文.xml

<util:map id="transportMap" key-type="java.lang.String" value-type="org.cometd.client.transport.ClientTransport">
    <entry key="websocket" value-ref="websocketTransport" />
    <entry key="long-polling" value-ref="longPollingTransport" />
</util:map>
<bean id="cometDClient" class="com.client.CometDClient" />

然后在 CometDClient.java 中:

@Inject
private Map<String, ClientTransport> transportMap;

"websocket":websocketTransport, "long-polling":longPollingTransport但是,我得到的不是以 . 的映射结束的地图,而是"websocketTransport":websocketTransport, "longPollingTransport":longPollingTransport.

换句话说,豆子的名字被用作我的钥匙!我在这里做错了什么吗?看起来即使对我来说它也应该足够防白痴。

4

2 回答 2

3

尝试以下操作:

import javax.annotation.Resource;

@Resource(name = "transportMap")
private Map<String, ClientTransport> transportMap;

问题是当 Spring 看到一个 Map 被自动装配时,它会将该类型的 bean 注入到该字段中,并将 bean 名称作为映射中的键。(与 List 的行为相同,它会将类型的 bean 注入到列表中)。解决方法是使用@Resource,它强制按名称自动装配。

这是来自 Spring参考文档的引用:

作为这种语义差异的特定结果,本身定义为集合或映射类型的 bean 不能通过 @Autowired 注入,因为类型匹配不适用于它们。对此类 bean 使用 @Resource,通过唯一名称引用特定的集合或映射 bean。”

于 2013-10-04T17:36:58.160 回答
1

我现在没有任何东西可以测试这个,所以出去走走......

我认为 Spring 只会“看到”您要求使用ClientTransport-implementations 作为值的映射,并将 bean 名称作为键,因此它实际上并没有注入transportMap您在 xml 中定义的内容。你可以尝试使用

@Inject
@Qualifier("transportMap")
private Map<String, ClientTransport> transportMap;

看看它是否有帮助。

于 2013-10-04T16:24:08.007 回答