Spring定义的map将bean名称作为键而不是指定的键值

时间:2013-10-04 15:56:17

标签: java spring

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

应用-context.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

换句话说, bean 的名称被用作我的键!我在这里做错了吗?即使对我来说,它看起来应该是足够的白痴。

2 个答案:

答案 0 :(得分:2)

尝试以下方法:

import javax.annotation.Resource;

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

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

以下是Spring reference docs的引用:

  

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

答案 1 :(得分:1)

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

我认为Spring只是“看到”你要求一个带有ClientTransport的实例 - 实现作为值,并将bean名称作为键,所以实际上并没有注入你在xml中定义的transportMap 。你可以尝试使用

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

看看它是否有帮助。