Autowiring Map not working as expected
I'm using Spring 3.0.4. I have some beans that use the @Autowired annotation on Maps. These maps are defined within an application-context.xml file (as these maps are constructed using several factory methods).
When I use my debugger, I can see the map gets constructed using the properly (expected) bean id. However, once the autowiring process starts, it claims it cannot find a bean with the id that just has been created.
Piece of code:
@Autowired
@Qualifier("dienstverbandMap")
private Map<String, String> dienstverbandMap;
Piece of context xml:
<bean class="jav开发者_StackOverflow中文版a.util.HashMap" id="dienstverbandMap" factory-bean="someFactoryMethod" factory-method="getMappedMap"/>
Important detail, when I change the type to java.lang.Object in both my Class and the context xml it does get wired In fact, I can cast it to a HashMap in my code and get everything to work. But that is not what i want obviously.
Anyone got an explantion what I'm doing wrong?
3.11.3. Fine-tuning annotation-based autowiring with qualifiers:
Quote: If you intend to express annotation-driven injection by name, do not primarily use @Autowired - even if is technically capable of referring to a bean name through @Qualifier values. Instead, prefer the JSR-250 @Resource annotation which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans which are themselves defined as a collection or map type cannot be injected via @Autowired since type matching is not properly applicable to them. Use @Resource for such beans, referring to the specific collection/map bean by unique name.
I think this is something to do with the type parameters for dienstverbandMap
. The injection can only be performed safely if Spring can figure out that the bean instance (a HashMap
) was actually instantiated as a HashMap<String, String>
. Spring could be losing the type parameters because of the bean's declared type is a raw type.
Another possibility is that the result signature of the factory method is wrong; e.g. Map instead of HashMap, or a raw HashMap rather than a HashMap<String, String>
.
(Some of these theories could be disproved if you showed us the declaration of the factory method.)
By the way, according to the comments in the spring-beans 2.0 DTD and 3.0 XSD, the class
attribute is not used if you supply a factory-bean
attribute. Have you tried leaving it out entirely?
I'm pretty sure your factory method returns java.util.Map
, not java.util.HashMap
, so I guess you could probably do this:
<bean class="java.util.Map" id="dienstverbandMap"
factory-bean="someFactoryMethod" factory-method="getMappedMap"/>
Disclaimer: I'm not sure if Spring will let you do that as Map
is an interface, but it's worth a try.
The bean definition for the map does not contain the type parameters, so auto-wiring cannot confirm that it is of the correct type.
If you use <util:map>
you can specify the type parameters, but then obviously can't use your own factory method. The only other solutions are to make your bean require a raw Map
(bad) or explicitly wire the maps in the bean definition (better).
精彩评论