2009-07-23 11 views
38

tengo una clase EnumPrimavera - ¿Cómo establecer las claves de enumeración en un mapa con anotaciones

public enum MyEnum{ 
    ABC; 
} 

que la clase de mi 'Mick' tiene esta propiedad

private Map<MyEnum, OtherObj> myMap; 

tengo esta primavera configuración 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> 

y esto está bien.
Me gustaría reemplazar esta configuración xml con anotaciones de Spring.
¿Tiene alguna idea sobre cómo conectar automáticamente el mapa?

El problema aquí es que si cambio de configuración XML para la anotación @Autowired (en el atributo de la clase myMap Mick) Primavera es tirar esta excepción

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

La primavera es no más capaz de reconocer la cadena ABC como un objeto MyEnum.ABC.
¿Alguna idea?

Gracias

+0

No está claro lo que estás tratando de hacer. ¿En qué tipo de anotaciones estás pensando? – skaffman

+0

Me gustaría utilizar la anotación @Autowired pero no está funcionando. ¿Tengo que especificar algo más para decirle a Spring que trate ese valor clave como un Enum en lugar de un String? – mickthompson

Respuesta

44

Esto funcionó para mí ...

Mi contexto de aplicación de primavera:

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

Mi clase donde el Map consigue inyectando:

public class MyClass { 

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

Las cosas importantes a destacar son que, en el contexto de Spring utilicé SpEL (Spring Expression Language) que solo está disponible desde la versión 3.0. Y en mi clase usé @Resource, ni @Inject (no funcionó) ni @Autowired (no probé esto).La única diferencia que conozco entre @Resource y @Autowired es que la primera se autoinyecta por nombre de bean mientras que la última lo hace por tipo de bean.

¡Disfrútalo!

+9

Recuerde usar '$' en lugar de '.' para separar una enumeración interna de una clase externa en Spring EL. –

+6

Solo un seguimiento que '@ Autowired' también arrojará' Key type [class com.foo.Bar $ BAZ] del mapa [java.util.Map] debe ser asignable a [java.lang.String] ',' @ Resource' es el ganador. +1 @Amir, '$' es un gotcha. – markdsievers

+0

La pregunta decía "Me gustaría * reemplazar * esta configuración xml con anotaciones de Spring". sin embargo, todavía hay XML de configuración aquí. ¿Eso significa que no puedes hacer esto en Spring simplemente con anotaciones? – Jonik

1

debe ser:

public class Mick { 

    private Map<MyEnum, OtherObj> myMap; 

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

Tenga una mirada en http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

Actualizado

El problema es que de acuerdo con el esquema util, no se puede especificar la clave o tipos de valores Sin embargo, puede implementar un MapFactoryBean propio (simplemente herede de org.springframework.beans.factory.config.MapFactoryBean). Un ceveat: observe que la definición genérica (incluso el pensamiento borrado en tiempo de ejecución) no interfiere.

+0

Hola David, sé acerca de la anotación @Autowired. Aquí el problema es que si conecto el mapa de manera automática, Spring ya no puede reconocer la cadena ABC como un objeto MyEnum.ABC. Con la configuración XML funciona bien, con la configuración de anotaciones está lanzando esta Excepción la excepción anidada es org.springframework.beans.FatalBeanException: El tipo de clave [clase com.MyEnum] del mapa [java.util.Map] debe ser asignable a [java. lang.String] – mickthompson

+0

He actualizado mi respuesta. –

0

El elemento <util:map> tiene llave, resp. atributos de tipo de valor, que representa la clase de las claves, resp. Los valores. Si especifica la clase totalmente calificada de su enumeración en el atributo de tipo de clave, las claves se analizan en esa enumeración al crear el mapa.

Spring verifica durante la inyección que la clave del mapa y los tipos de valores -como se declara en la clase que contiene el mapa- son compatibles con la asignación con los tipos de clave y valor del bean del mapa. De hecho, es de donde obtienes la excepción.

15

Este me dio ajustes, pero pude juntarlo usando la respuesta de David y algunos otros enlaces (abajo).

  • no cambie los nombres de las propiedades en la declaración de MapFactoryBean.
  • asegúrese de que el atributo de tipo clave apunte a la enumeración que desea usar como clave en el mapa.

Clase

@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 archivo de configuración:

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

ENLACES

5

contexto de aplicación

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

clase Java

package com.project; 

public class MapProvider { 

    private Map<MyEnum, ValueObject> myMap; 

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

La respuesta necesita una explicación un poco más de lo que enumeró aquí. – Markus

+0

Creé el mapa con enum como clave y lo usé para el argumento setter. Pensé que es obvio :) –

Cuestiones relacionadas