Spring 无法自动装配 Map bean

Posted

技术标签:

【中文标题】Spring 无法自动装配 Map bean【英文标题】:Spring can't autowire Map bean 【发布时间】:2012-12-04 12:35:43 【问题描述】:

我在 spring 中这样定义了一张地图:

<util:map id="AdditionalParams" scope="prototype" map-class="java.util.HashMap" 
          key-type="java.lang.String" value-type="java.lang.String">
    
    <entry key="Start" value="12345" />
    <entry key="Finish" value="12365" />
</util:map>

然后我将此 bean 自动装配到定义为的属性:

private @Autowired @Qualifier(value = "AdditionalParams") Map<String, String> additionalParams;

执行此操作时,会抛出异常:

原因:org.springframework.beans.factory.BeanCreationException:创建名为“DutyCreator”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 java.util.Map DutyCreator.additionalParams;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项 [map with value type java.lang.String] 找到类型为 [java.lang.String] 的匹配 bean:预计至少有 1 个符合自动装配候选资格的 bean对于这种依赖。依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=AdditionalParams)

原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项 [map with value type java.lang.String] 找到类型为 [java.lang.String] 的匹配 bean:预计至少有 1 个符合条件的 bean作为此依赖项的自动装配候选者。依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=AdditionalParams)

有什么想法吗?

干杯。

【问题讨论】:

请分享您的应用上下文文件。 你也可以使用&lt;util:map&gt;xml配置 【参考方案1】:

从 Spring 4.3 开始,@Autowiredcan inject lists and maps 和问题中的给定代码将起作用:

也就是说,从 4.3 开始,集合/映射和数组类型也可以通过 Spring 的 @Autowired 类型匹配算法进行匹配,只要元素类型信息保留在 @Bean 返回类型签名或集合继承层次结构中.

但是对于较低的 Spring 版本,您无法自动装配这样的集合。但是,您可以执行以下操作:

@Resource(name="AdditionalParams")
private Map<String, String> additionalParams;

甚至:

@Value("#AdditionalParams")
private Map<String, String> additionalParams;

查看spring docs,提示部分:

本身定义为集合或映射类型的 bean 不能 通过@Autowired 注入,因为类型匹配不正确 适用于他们。对此类 bean 使用 @Resource

【讨论】:

完美。正是我要找的.. 谢谢。这对我有用.. @Resource(name="AdditionalParams") 谢谢,这很不直观;我现在对maputil:map 的了解比我想的要多:-/ 哇,我已经花了几个小时来解决这个问题。为什么 Spring 只使用 autowire 而不是 Resource?这种方式只会让 Spring 使用起来很烦人。 对于那些仍然没有帮助的人,不要忘记删除 @Qualifier(name="AdditionalParams") 否则它将不起作用。 有人有@Autowired 的完整工作示例吗?仍然不适合我。【参考方案2】:

似乎您的 @Qualifier(value = "AdditionalParams") 不起作用。

通过以下注释尝试使用地图:

@Resource
private Properties AdditionalParams;

并保持您的 applicationContext.xml 文件完整。

【讨论】:

【参考方案3】:
@Autowired ApplicationContext ctx;
private  <T> T getBean(String qualifier, Class<T> returnType)
    //use this for loop to print all bean from ctx. so you wont miss the typo.
    /*for(String s:ctx.getBeanDefinitionNames())
        log.info(s);*/
    return ctx.getBean(qualifier, returnType);

// 在你的通话中

 if(providerList == null)
       providerList = ctx.getBean("providerList", Map.class);
 

这个解决方案对我很有效

【讨论】:

以上是关于Spring 无法自动装配 Map bean的主要内容,如果未能解决你的问题,请参考以下文章

spring bean自动装配

创建 bean 时出错。注入自动装配的依赖项失败。无法自动装配字段

Spring--自动装配

无法自动装配bean,我正在使用Spring 3.1

Spring:无法从父上下文自动装配 bean

3.spring:自动装配/Bean之间的关系/作用域/外部文件/spel/