Spring - 如何在带有注释的Map中设置Enum键

时间:2009-07-23 20:34:33

标签: spring enums annotations

我有一个Enum课程

public enum MyEnum{
    ABC;
}

比我的'Mick'类有这个属性

private Map<MyEnum, OtherObj> myMap;

我是这个春天的xml配置。

<util:map id="myMap">
    <entry key="ABC" value-ref="myObj" />
</util:map>

<bean id="mick" class="com.x.Mick">
    <property name="myMap" ref="myMap" />
</bean>

这很好。
我想用Spring注释替换这个xml配置 您对如何自动装配地图有任何想法吗?

这里的问题是,如果我从xml配置切换到@Autowired注释(在Mick类的myMap属性上),Spring会抛出此异常

nested exception is org.springframework.beans.FatalBeanException: Key type [class com.MyEnum] of map [java.util.Map] must be assignable to [java.lang.String]

Spring不再能够将字符串ABC识别为MyEnum.ABC对象。
有什么想法吗?

谢谢

7 个答案:

答案 0 :(得分:46)

这对我有用......

My Spring应用程序上下文:

<util:map id="myMap">
  <entry key="#{T(com.acme.MyEnum).ELEM1}" value="value1" />
  <entry key="#{T(com.acme.MyEnum).ELEM2}" value="value2" />
</util:map>

注入Map的班级:

public class MyClass {

    private @Resource Map<MyEnum, String> myMap;
}

需要注意的重要事项是,在Spring上下文中,我使用了SpEL(Spring Expression Language),它仅在3.0版本之后可用。在我的课堂上,我使用@Resource@Inject(它对我不起作用)和@Autowired(我没试过)。我在@Resource@Autowired之间唯一的区别是,前者通过bean名称自动注入,而后者则通过bean类型进行自动注入。

享受!

答案 1 :(得分:16)

这个给了我适合但我能够使用David的答案和其他一些链接(下面)将它拼凑在一起。

  • 不要更改MapFactoryBean声明中属性的名称。
  • 确保key-type属性指向要用作地图中键的枚举。

<强>类

@Component
public class MyClass {

    private Map<MyEnum, ValueObjectInterface> valueMap;

    @Autowired
    public void setValueMap(final Map<MyEnum, ValueObjectInterface> valueMap) {
        this.valueMap= valueMap;
    }


}

<强>枚举

    public enum MyEnum{
    FOO ("FOO"),
    BAR ("BAR"),
    BAZ ("BAZ");
}

XML配置文件:                   

<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" />

<强>链接

答案 2 :(得分:5)

申请背景

<?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类

package com.project;

public class MapProvider {

    private Map<MyEnum, ValueObject> myMap;

    public void setMyMap(Map<MyEnum, ValueObject> myMap) {
        this.myMap = myMap;
    }
}

答案 3 :(得分:1)

应该是:

public class Mick {

  private Map<MyEnum, OtherObj> myMap;

  @Autowired
  public void setMyMap(Map<MyEnum, OtherObj> myMap) {
    this.myMap = myMap;
  }
}

查看http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

<强>更新

问题是,根据util模式,您无法指定键或值类型。但是,您可以实现自己的MapFactoryBean(仅从org.springframework.beans.factory.config.MapFactoryBean继承)。一个ceveat - 注意通用定义(甚至认为在运行时擦除)不会妨碍。

答案 4 :(得分:0)

<util:map>元素具有键类型,resp。 value-type属性,表示键的类,resp。价值。如果在key-type属性中指定枚举的完全限定类,则在创建映射时会将键解析为该枚举。

Spring在注入期间验证在包含map的类中声明的map的键和值类型是否与map bean的键和值类型分配兼容。这实际上就是你从中获得例外的地方。

答案 5 :(得分:0)

您只需要使用具体的Map类作为HashMap而不是抽象或接口:

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() { .. }
}

答案 6 :(得分:0)

如果您有一个Map值作为键的Enum,请考虑使用Java的EnumMap实现:

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

在这里您还可以看到Baeldung帖子,其中包含一些使用示例:

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