Подтвердить что ты не робот

Spring - Как вы устанавливаете ключи Enum на карте с аннотациями

У меня класс Enum

public enum MyEnum{
    ABC;
}

чем мой класс "Мик" имеет это свойство

private Map<MyEnum, OtherObj> myMap;

У меня есть эта конфигурация spring 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>

и это нормально.
Я бы хотел заменить эту xml-конфигурацию аннотациями spring.
Есть ли у вас какие-либо идеи о том, как автоувеличивать карту?

Проблема заключается в том, что если я перейду из xml config в @Autowired аннотацию (в атрибуте myMap класса Mick) 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.
Любая идея?

Спасибо

4b9b3361

Ответ 1

Это сработало для меня...

Мой контекст приложения 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.

Наслаждайтесь!

Ответ 2

Этот вопрос дал мне возможность, но я смог собрать его вместе, используя ответ Дэвида и некоторые другие ссылки (ниже).

  • не изменяют имена свойств в объявлении MapFactoryBean.
  • убедитесь, что атрибут key-type указывает на перечисление, которое вы хотите использовать в качестве ключа на карте.

Класс

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

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

ССЫЛКА

Ответ 3

Контекст приложения

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

Ответ 4

Должно быть:

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

Обновление

Проблема заключается в том, что согласно схеме использования вы не можете указывать типы ключей или значений. Однако вы можете реализовать собственный MapFactoryBean (просто наследуйте от org.springframework.beans.factory.config.MapFactoryBean). Один ceveat - обратите внимание, что общее определение (даже стираемое во время выполнения) не мешает.

Ответ 5

Элемент <util:map> имеет тип ключа, соответственно. атрибуты value-type, которые представляют класс ключей, соответственно. ценности. Если вы укажете полностью квалифицированный класс вашего перечисления в атрибуте key-type, тогда ключи будут разбираться в этом перечислении при создании карты.

Spring проверяет во время инъекции, что ключ карты и типы значений, объявленные в классе, содержащем карту, являются совместимыми с назначением и ключевыми типами карты bean. На самом деле вы получаете исключение.

Ответ 6

Вам просто нужно использовать конкретный класс 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() { .. }
}