[ACCEPTED]-Spring - How do you set Enum keys in a Map with annotations-annotations
This worked for me...
My Spring application 10 context:
<util:map id="myMap">
<entry key="#{T(com.acme.MyEnum).ELEM1}" value="value1" />
<entry key="#{T(com.acme.MyEnum).ELEM2}" value="value2" />
</util:map>
My class where the Map
gets injected:
public class MyClass {
private @Resource Map<MyEnum, String> myMap;
}
The 9 important things to note are that in the 8 Spring context I used SpEL (Spring Expression 7 Language) which is only available since 6 version 3.0. And in my class I used @Resource
, neither 5 @Inject
(it didn't work for me) nor @Autowired
(I didn't 4 try this). The only difference I'm aware 3 of between @Resource
and @Autowired
, is that the former auto-inject 2 by bean name while the later does it by 1 bean type.
Enjoy!
This one gave me fits but I was able to 2 piece it together using David's answer and 1 some other links (below).
- do not change the names of the properties in the MapFactoryBean declaration.
- ensure that key-type attribute points to the enum that you want to use as a key in the map.
Class
@Component
public class MyClass {
private Map<MyEnum, ValueObjectInterface> valueMap;
@Autowired
public void setValueMap(final Map<MyEnum, ValueObjectInterface> valueMap) {
this.valueMap= valueMap;
}
}
Enum
public enum MyEnum{
FOO ("FOO"),
BAR ("BAR"),
BAZ ("BAZ");
}
XML Config file:
<bean id="valueMap" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="targetMapClass">
<value>java.util.HashMap</value>
</property>
<property name="sourceMap">
<map key-type="com.company.packagepath.MyEnum">
<entry key="FOO" value-ref="valueObject1" />
<entry key="BAR" value-ref="valueObject2" />
<entry key="BAZ" value-ref="valueObject3" />
</map>
</property>
</bean>
<bean id="valueObject1" class="com.company.packagepath.ValueObject1" />
<bean id="valueObject2" class="com.company.packagepath.ValueObject2" />
<bean id="valueObject3" class="com.company.packagepath.ValueObject3" />
LINKS
Application context
<?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.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd ">
<bean id="myProvider" class="com.project.MapProvider">
<property name="myMap" ref="myMap"/>
</bean>
<util:map id="myMap" key-type="com.project.MyEnum" value-type="com.project.ValueObject">
<entry>
<key><value type="com.project.MyEnum">FOO</value></key>
<ref bean="objectValue1"/>
</entry>
</util:map>
</beans>
Java class
package com.project;
public class MapProvider {
private Map<MyEnum, ValueObject> myMap;
public void setMyMap(Map<MyEnum, ValueObject> myMap) {
this.myMap = myMap;
}
}
0
Should be:
public class Mick {
private Map<MyEnum, OtherObj> myMap;
@Autowired
public void setMyMap(Map<MyEnum, OtherObj> myMap) {
this.myMap = myMap;
}
}
Have a look at http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config
Updated
The problem is 7 that according to the util schema, you cannot 6 specify the key or value types. You can 5 however to implement a MapFactoryBean of 4 your own (just inherit from org.springframework.beans.factory.config.MapFactoryBean). One 3 ceveat - notice that the generic definition 2 (even thought erased in runtime) doesn't 1 get in the way.
The <util:map>
element has key-type, resp. value-type 11 attributes, that represents the class of 10 the keys, resp. the values. If you specify 9 the fully qualified class of your enum in 8 the key-type attribute, the keys are then 7 parsed into that enum when creating the 6 map.
Spring verifies during injection that 5 the map's key and value types -as declared 4 in the class containing the map- are assignment-compatible 3 with the key and value types of the map 2 bean. This is actually where you get the 1 exception from.
You just need to use concrete Map
class as 1 HashMap
and not abstract or interface:
public class Mick {
private HashMap<MyEnum, OtherObj> myMap;
@Autowired
public void setMyMap(HashMap<MyEnum, OtherObj> myMap) {
this.myMap = myMap;
}
}
public class AppConfig
{
@Bean
public HashMap<MyEnum, OtherObj> myMap() { .. }
}
If you have a Map
with an Enum
values as keys, then 3 consider using Java's EnumMap
implementation:
https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/EnumMap.html
Here 2 you also have a Baeldung post with some 1 examples on how to use it:
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.