【问题标题】:Spring defined map has bean names as key instead of specified key valueSpring 定义的映射将 bean 名称作为键而不是指定的键值
【发布时间】:2013-10-04 15:56:16
【问题描述】:

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

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

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

【问题讨论】:

    标签: java spring


    【解决方案1】:

    尝试以下方法:

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

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

    这是春天reference docs的引述:

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

    【讨论】:

      【解决方案2】:

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

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

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

      看看有没有帮助。

      【讨论】:

      • @Qualifier 显然不能用于装饰字段。不过感谢您的回答。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2019-05-21
      相关资源
      最近更新 更多