2009-07-23 10 views
38

ich eine Enum-Klasse habenSpring - Wie stellen Sie Enum Schlüssel in einer Karte mit Anmerkungen

public enum MyEnum{ 
    ABC; 
} 

als meine 'Mick' Klasse hat diese Eigenschaft

private Map<MyEnum, OtherObj> myMap; 

ich in diesem Frühjahr haben XML-Konfiguration.

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

und das ist in Ordnung.
Ich möchte diese XML-Konfiguration durch Spring-Anmerkungen ersetzen.
Haben Sie eine Idee, wie Sie die Karte automatisch ansteuern können?

Das Problem hier ist, dass, wenn ich von XML-Konfigurations zur @Autowired Annotation wechseln (auf dem myMap Attribute der Mick-Klasse) Frühlings diese Ausnahme

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

Den Frühling ist nicht mehr in der Lage ist, werfen zu erkennen die Zeichenfolge ABC als ein MyEnum.ABC-Objekt.
Irgendeine Idee?

Dank

+0

Es ist nicht klar, was Sie zu tun versuchen. An welche Art von Anmerkungen denken Sie? – skaffman

+0

Ich möchte die @Autowired Annotation verwenden, aber es funktioniert nicht. Muss ich etwas anderes angeben, um Spring mitzuteilen, dass dieser Schlüsselwert als Enum statt als String behandelt wird? – mickthompson

Antwort

44

Dieser arbeitete für mich ...

Kontext Mein Frühling Anwendung:

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

Meine Klasse, wo die Map injiziert wird:

public class MyClass { 

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

Die wichtigen Dinge sind zu beachten, dass in Im Spring-Kontext habe ich SPEL (Spring Expression Language) verwendet, das erst seit Version 3.0 verfügbar ist. Und in meiner Klasse benutzte ich @Resource, weder @Inject (es funktionierte nicht für mich) noch @Autowired (ich habe das nicht versucht).Der einzige Unterschied, den ich zwischen @Resource und @Autowired kenne, ist, dass der ehemalige automatisch nach Bean-Namen injiziert, während der spätere nach Bean-Typ.

Viel Spaß!

+9

Denken Sie daran, '$' anstelle von '.' zum Trennen einer inneren Enum von einer äußeren Klasse in Spring EL. –

+6

Nur eine Folge, die '@ Autowired' ergibt auch' Schlüsseltyp [Klasse com.foo.Bar $ BAZ] der Karte [java.util.Map] muss [java.lang.String] ',' @ zuweisbar sein Ressource ist der Gewinner. +1 @Amir, '$' ist eine Frage. – markdsievers

+0

Frage: "Ich möchte * diese XML-Konfiguration durch Spring-Anmerkungen ersetzen." Dennoch gibt es hier noch Config-XML. Bedeutet das, dass du das im Frühling nicht nur mit Anmerkungen machen kannst? – Jonik

1

Sollte sein:

public class Mick { 

    private Map<MyEnum, OtherObj> myMap; 

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

einen Blick auf http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

aktualisiert

Das Problem ist, dass die util-Schema nach, Sie den Schlüssel nicht angeben oder Werttypen. Sie können jedoch eine eigene MapFactoryBean implementieren (erben Sie einfach von org.springframework.beans.factory.config.MapFactoryBean). Ein ceveat - beachten Sie, dass die generische Definition (auch in Laufzeit gelöscht) nicht in die Quere kommen.

+0

Hallo David, ich kenne die @Autowired Annotation. Hier ist das Problem, dass wenn ich die Karte autowire, Spring nicht mehr in der Lage ist, die Zeichenkette ABC als ein MyEnum.ABC-Objekt zu erkennen. Mit der XML-Konfiguration funktioniert es gut, mit der Annotationskonfiguration, die es wirft Exception verschachtelte Ausnahme ist org.springframework.beans.FatalBeanException: Schlüsseltyp [Klasse com.MyEnum] der Karte [java.util.Map] muss zu [java. lang.String] – mickthompson

+0

Ich habe meine Antwort aktualisiert. –

0

Das Element <util:map> hat einen Schlüsseltyp bzw. value-type-Attribute, die die Klasse der Schlüssel bzw. die Werte. Wenn Sie im Schlüsselattribut die vollständig qualifizierte Klasse Ihrer Enumeration angeben, werden die Schlüssel beim Erstellen der Map in diese Enumeration zerlegt.

Spring überprüft während der Injektion, dass die Schlüssel- und Werttypen der Map - wie in der Klasse mit der Map deklariert - zu den Schlüssel- und Werttypen der Map-Bean zuweisungskompatibel sind. Hier erhalten Sie die Ausnahme von.

15

Dieser gab mir Anfälle, aber ich war in der Lage, es zusammen mit Davids Antwort und einigen anderen Links (unten) zu setzen.

  • Ändern Sie nicht die Namen der Eigenschaften in der MapFactoryBean-Deklaration.
  • Stellen Sie sicher, dass das Attribut key-type auf die Enumeration verweist, die Sie als Schlüssel in der Map verwenden möchten.

Klasse

@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-Datei:

<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

Anwendungskontext

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

package com.project; 

public class MapProvider { 

    private Map<MyEnum, ValueObject> myMap; 

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

Die Antwort braucht ein bisschen mehr Erklärung von dem, was Sie hier aufgelistet haben. – Markus

+0

Ich habe Karte mit enum als Schlüssel erstellt und sie für das Setter-Argument verwendet. Ich dachte es ist offensichtlich :) –

Verwandte Themen