Spring - How do you set Enum keys in a Map with annotations

后端 未结 7 543
有刺的猬
有刺的猬 2020-12-13 09:08

I\'ve an Enum class

public enum MyEnum{
    ABC;
}

than my \'Mick\' class has this property

private Map

        
相关标签:
7条回答
  • 2020-12-13 09:22

    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 讨论(0)
  • 2020-12-13 09:31

    If you have a Map with an Enum values as keys, then consider using Java's EnumMap implementation:

    https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/EnumMap.html

    Here you also have a Baeldung post with some examples on how to use it:

    https://www.baeldung.com/java-enum-map

    0 讨论(0)
  • 2020-12-13 09:36

    The <util:map> element has key-type, resp. value-type attributes, that represents the class of the keys, resp. the values. If you specify the fully qualified class of your enum in the key-type attribute, the keys are then parsed into that enum when creating the map.

    Spring verifies during injection that the map's key and value types -as declared in the class containing the map- are assignment-compatible with the key and value types of the map bean. This is actually where you get the exception from.

    0 讨论(0)
  • 2020-12-13 09:43

    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 that according to the util schema, you cannot specify the key or value types. You can however to implement a MapFactoryBean of your own (just inherit from org.springframework.beans.factory.config.MapFactoryBean). One ceveat - notice that the generic definition (even thought erased in runtime) doesn't get in the way.

    0 讨论(0)
  • 2020-12-13 09:48

    This worked for me...

    My Spring application 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 important things to note are that in the Spring context I used SpEL (Spring Expression Language) which is only available since version 3.0. And in my class I used @Resource, neither @Inject (it didn't work for me) nor @Autowired (I didn't try this). The only difference I'm aware of between @Resource and @Autowired, is that the former auto-inject by bean name while the later does it by bean type.

    Enjoy!

    0 讨论(0)
  • 2020-12-13 09:48

    This one gave me fits but I was able to piece it together using David's answer and 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

    • Code Ranch
    • Spring MapFactoryBean example at mkyong.com
    • How assign bean's property an Enum value in Spring config file?
    0 讨论(0)
提交回复
热议问题