ChatGPT解决这个技术问题 Extra ChatGPT

Spring can't autowire Map bean

I've defined a map in spring as such:

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

And then I'm autowiring this bean to a property defined as:

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

When doing this, the an exception get's thrown saying that:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DutyCreator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.Map DutyCreator.additionalParams; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=AdditionalParams)} Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=AdditionalParams)}

Any ideas?

Cheers.

Please share your application Context file.
You may also use the <util:map> xml configuration

T
Tunaki

Starting with Spring 4.3, @Autowired can inject lists and maps and the given code in the question would work:

That said, as of 4.3, collection/map and array types can be matched through Spring’s @Autowired type matching algorithm as well, as long as the element type information is preserved in @Bean return type signatures or collection inheritance hierarchies.

But with a lower Spring version, you can't autowire a collection like that. However, you can do the following:

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

or even:

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

Check the spring docs, the tips section:

beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans


perfect. exactly what i was looking for.. Thanks. this worked for me.. @Resource(name="AdditionalParams")
Thanks, this was very unintuitive; I now know more about map and util:map than I wanted to :-/
Wow, I already spent hours on this problem. Why Spring just use autowire instead of Resource? This way just make Spring so annoying to use.
For those to whom this still won't help, don't forget to remove @Qualifier(name="AdditionalParams") or else it won't work.
Does anybody have a complete working example for @Autowired? Still not working for me.
A
Amber

Seems like your @Qualifier(value = "AdditionalParams") is not working.

Try using the map by following annotation :

@Resource
private Properties AdditionalParams;

and keeping your applicationContext.xml file intact.


R
Ramkumar Pillai
@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);
}

// inside your call

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

This Solution works good to me