开发者

Autowiring Map not working as expected

开发者 https://www.devze.com 2023-02-09 23:50 出处:网络
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 factor

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

0

精彩评论

暂无评论...
验证码 换一张
取 消