2009-07-23 12 views
38

私はEnumクラスを持っています。春 - アノテーション付きのマップでEnumキーを設定する方法

public enum MyEnum{ 
    ABC; 
} 
私の 'Mick'クラスはこのプロパティを持っています。

private Map<MyEnum, OtherObj> myMap; 

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

これは問題ありません。
このxml構成をSpringアノテーションに置き換えたいと思います。
マップを自動配線する方法はありますか?

xml configから@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オブジェクトとして返します。
いいですか?

ありがとう

+0

それはあなたが何をしようとしては明らかではありません。どのようなアノテーションを考えていますか? – skaffman

+0

@Autowired注釈を使用したいと思いますが、機能していません。 SpringがStringの代わりにEnumとしてそのKey値を扱うように指示するには何か他を指定する必要がありますか? – mickthompson

答えて

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 Expression Language)を使用しましたが、これはバージョン3.0以降でのみ利用可能です。私の授業では@Resourceを使用しましたが、@Inject(それは私のためには機能しませんでした)でも@Autowired(私はこれを試していませんでした)もありませんでした。私が@Resource@Autowiredの間で気づいている唯一の違いは、前者がBeanの名前で自動注入し、後でBeanのタイプで行うことです。

お楽しみください!

+9

'。'の代わりに '$'を使用することを忘れないでください。 Spring ELの内部クラスを外部クラスから分離するためのクラスです。 –

+6

'@ Autowired'は' java.util.Map 'のキータイプ[class com.foo.Bar $ BAZ]も[java.lang.String] 'に代入可能でなければならない'リソースは優勝者です。 +1 @Amir、 '$'は勘違いです。 – markdsievers

+0

質問: "このxml構成を* Springアノテーションに置き換えたいです。"まだここに設定XMLがあります。純粋にアノテーションを使ってSpringでこれを行うことはできませんか? – Jonik

1

は次のようになります。

public class Mick { 

    private Map<MyEnum, OtherObj> myMap; 

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

は、問題がutilのスキーマに従って、あなたがキーを指定することはできませんということです

を更新しましたhttp://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

を見てくださいまたは値の型。しかし、独自のMapFactoryBeanを実装することができます(org.springframework.beans.factory.config.MapFactoryBeanから継承したもの)。 1つのセヴェット - 一般的な定義(実行時に消えてしまったと思っても)が途中で取り込まれないことに注意してください。

+0

こんにちはDavid、@Autowiredアノテーションについて知っています。ここで問題となるのは、マップをオートワイヤリングすると、Springが文字列ABCをMyEnum.ABCオブジェクトとして認識できなくなるということです。 XML設定では、アノテーションの設定で例外がスローされます。 ネストされた例外はorg.springframework.beans.FatalBeanExceptionです。マップ[java.util.Map]のキータイプ[class com.MyEnum]は[java。 lang.String] – mickthompson

+0

私は自分の答えを更新しました。 –

0

<util:map>要素にはキータイプがあります。キーのクラスrespを表すvalue-type属性。その価値。 key-type属性で列挙型の完全修飾クラスを指定すると、マップを作成するときにその列挙型にキーが解析されます。

Springは、マップを含むクラスで宣言されているマップのキーと値の型が、マップBeanのキーと値の型に割り当て互換性があることを注入時に検証します。これは実際にあなたがどこから例外を得るかです。

15

これは私にフィット感を与えましたが、私は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" /> 

リンク

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

答えはあなたがここに挙げたもののもう少し説明が必要です。 – Markus

+0

私はenumをキーとしてマップを作成し、setter引数として使用しました。私はそれが明らかだと思った:) –

関連する問題