2009-07-23 65 views
38

一个地图我有一个枚举类春天 - 如何设置枚举密钥与注释

public enum MyEnum{ 
    ABC; 
} 

比我的“米克·”类具有此属性

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注解(在米克类的MYMAP属性)春引发此异常

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

春天不再能够识别字符串ABC作为MyEnum.ABC对象。
有什么想法?

感谢

+0

目前尚不清楚你想要做什么。你在想什么样的注释? – skaffman 2009-07-24 16:44:55

+0

我想使用@Autowired注解,但它不起作用。我是否必须指定别的东西来告诉Spring将该Key值视为Enum而不是String? – mickthompson 2009-07-26 11:53:01

回答

44

这个工作对我来说...

我的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表达式语言),它只能从3.0版本开始使用。而在我的班级中,我使用的是@Resource,既没有@Inject(也没有为我工作),也没有@Autowired(我没有试过这个)。我知道的唯一区别是@Resource@Autowired,前者是通过bean名自动注入的,而后者是通过bean类来注入的。

享受!

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 - 注意通用定义(即使在运行时被删除)也不会妨碍。

+0

嗨大卫,我了解@Autowired注释。这里的问题是,如果我自动装载地图,Spring不再能够将字符串ABC识别为MyEnum.ABC对象。随着XML配置能正常工作,与注释配置它抛出这个异常 嵌套的例外是org.springframework.beans.FatalBeanException:地图的主要类型[类com.MyEnum] [java.util.Map]必须分配给【JAVA。 lang.String] – mickthompson 2009-07-26 11:46:47

+0

我已经更新了我的答案。 – 2009-07-26 15:09:26

0

<util:map>元素具有键型,值类型属性,表示键的类别,价值。如果您在键类型属性中指定了枚举的完全限定类,那么在创建映射时键将被解析为该枚举。注射,地图的键和值类型 - 如在包含MAP-类中声明是赋值兼容键和值类型的地图豆的过程中

春天验证。这实际上是你从中得到例外的地方。

15

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

  • 不会更改MapFactoryBean声明中属性的名称。
  • 确保键类型属性指向要用作映射中键的枚举。

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

LINKS

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; 
    } 
}