20

I have a Spring map problem that is bringing me to tears.

My spring looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
    ">

   <util:map id="mockMap">
        <entry key="userTest1" value="test1"/>
        <entry key="userTest2" value="test2"/>
        <entry key="userTest3" value="test6"/>
    </util:map>
</beans>

Then the code where I am autowiring this is as follows (irrelevant parts ommitted):

@Autowired
@Resource(name="mockMap")
Map<String, String> testMap;

@Test
public void testGetGearListActivityOK() {
    for (String key : testMap.keySet()) {
        System.out.println("key = " + key);
    }
}

Amazingly enough, this will actually give me an error on the autowiring step saying that there are no beans matching type String. However, if I change the map in the unit-test to be defined as Map then I get the follow output:

[junit] key = mockMap
[junit] key = org.springframework.context.annotation.internalConfigurationAnnotationProcessor
[junit] key = org.springframework.context.annotation.internalAutowiredAnnotationProcessor
[junit] key = org.springframework.context.annotation.internalRequiredAnnotationProcessor
[junit] key = org.springframework.context.annotation.internalCommonAnnotationProcessor
[junit] key = systemProperties
[junit] key = systemEnvironment
[junit] key = messageSource
[junit] key = applicationEventMulticaster
[junit] key = lifecycleProcessor

I have not yet been able to get the key section of the entry to actually show up as a key. If I change the map back to Map and add some into my spring then the map populates with those, using their id's as the keys.

I'm so confused here and have used spring a decent amount in the past. If anyone has a clue what the heck is going on here I'd be very grateful.

Thanks in advance.

Also, I saw this question: Auto-wiring a List using util schema gives NoSuchBeanDefinitionException

But the solution there is to use @Resource, which I am already doing..

Community
  • 1
  • 1
Craig
  • 1,295
  • 3
  • 16
  • 29

3 Answers3

27

Remove @Autowired and only use the @Resource(name="mockMap")

Ryan
  • 326
  • 3
  • 5
  • 3
    The Autowired is overriding the Resource and so Spring is looking for the first Map object it has which happens to be the spring context. This is why you get the key's you mentioned as output. – dennisjtaylor Sep 07 '12 at 20:36
  • 2
    Actually what is happening is that if you use @Autowired on any collection it will look for any bean that matches your qualifier (or all beans of that type if you don't have a qualifier) and add them to the collection. If you don't have any beans of that type you will get a "no beans found, at least one expected" exception during the autowiring of that object. – Craig Sep 08 '12 at 00:02
  • 1
    today i spent 3 hrs on this :( – Nayn Oct 12 '12 at 02:57
1

you can't autowire a collection like that.

However, you can try these:

@Resource(name="mockMap")
private Map<String, String> testMap;

or even:

@Value("#{mockMap}")
private Map<String, String> testMap;

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

Zigri2612
  • 2,279
  • 21
  • 33
0

only use @Resource and change "testMap" to "mockMap" in your config

xiaohuo
  • 2,375
  • 1
  • 11
  • 11