Spring无法自动装配Map类型的bean。

61

我在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:无法连接字段:private java.util.Map DutyCreator.additionalParams;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为[java.lang.String]的匹配bean以满足依赖项[值类型为java.lang.String的map]:预期至少有一个bean符合此依赖关系的自动装配候选项。依赖项注解:{@org.springframework.beans.factory.annotation.Autowired(required = true),@org.springframework.beans.factory.annotation.Qualifier(value = AdditionalParams)}

由org.springframework.beans.factory.NoSuchBeanDefinitionException引起:找不到类型为[java.lang.String]的匹配bean以满足依赖项[值类型为java.lang.String的map]:预期至少有一个bean符合此依赖关系的自动装配候选项。依赖项注解:{@org.springframework.beans.factory.annotation.Autowired(required = true),@org.springframework.beans.factory.annotation.Qualifier(value = AdditionalParams)}



有任何想法吗?

谢谢。


请分享您的应用程序上下文文件。 - Amber
您也可以使用<util:map>的XML配置。 - Alex
3个回答

121

从Spring 4.3开始,@Autowired 可以注入列表和映射,并且问题中给出的代码将会生效:

话虽如此,自4.3以来,集合/映射和数组类型也可以通过Spring的@Autowired类型匹配算法进行匹配,只要元素类型信息在@Bean返回类型签名或集合继承层次结构中得到保留。

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

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

甚至可以:

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

请查看spring文档,提示部分:

自身定义为集合或映射类型的bean无法通过@Autowired注入,因为类型匹配不适用于它们。对于这样的bean,请使用@Resource。


1
完美,正是我所需要的。谢谢。 这对我有用。 @Resource(name="AdditionalParams") - Robin Bajaj
谢谢,这很不直观;现在我对maputil:map的了解比我想要的还多 :-/ - Cory Kendall
2
哇,我已经花了好几个小时在这个问题上了。为什么Spring不直接使用自动装配而选择@Resource注解呢?这样只会让Spring使用起来更加烦人。 - Evan Hu
对于那些仍然无法理解的人,请不要忘记删除@Qualifier(name="AdditionalParams"),否则它将无法工作。 - hipokito
有没有人有@Autowired的完整工作示例?对我来说还是不起作用。 - Markus Barthlen
即使在Spring 5.1版本中,使用@ Autowired注释的String键映射似乎仍然无法工作,只有使用@Resource才能正常工作。 - Matthew Wise

4

看起来你的@Qualifier(value = "AdditionalParams")没有起作用。

尝试使用以下注释中的映射:

@Resource
private Properties AdditionalParams;

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


2
@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);
 }

这个解决方案对我来说很有效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接