J'ai un cours d'énum
public enum MyEnum{
ABC;
}
que ma classe 'Mick' a cette propriété
private Map<MyEnum, OtherObj> myMap;
J'ai cette configuration de printemps 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>
et c'est bien.
J'aimerais remplacer cette configuration XML par des annotations Spring.
Avez-vous une idée sur la façon de virer automatiquement la carte?
Le problème ici est que si je passe de la configuration xml à l'annotation @Autowired (sur l'attribut myMap de la classe Mick), Spring lève cette exception.
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 n'est plus en mesure de reconnaître la chaîne ABC en tant qu'objet MyEnum.ABC.
Une idée?
Merci
Cela a fonctionné pour moi ...
Mon contexte d'application 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>
Ma classe où la Map
est injectée:
public class MyClass {
private @Resource Map<MyEnum, String> myMap;
}
Les points importants à noter sont que, dans le contexte Spring, j’utilisais SpEL (Spring Expression Language), qui n’est disponible que depuis la version 3.0. Et dans ma classe, j'ai utilisé @Resource
, ni @Inject
(cela n'a pas fonctionné pour moi) ni @Autowired
(je n'ai pas essayé cela). La seule différence que je connaisse entre @Resource
et @Autowired
est que l'ancien auto-injecte par nom de bean alors que le dernier le fait par type.
Prendre plaisir!
Celui-ci m'a donné des crises, mais j'ai pu le reconstituer en utilisant la réponse de David et quelques autres liens (ci-dessous).
Classe
@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");
}
Fichier de configuration 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" />
LIENS
Contexte d'application
<?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>
classe Java
package com.project;
public class MapProvider {
private Map<MyEnum, ValueObject> myMap;
public void setMyMap(Map<MyEnum, ValueObject> myMap) {
this.myMap = myMap;
}
}
Devrait être:
public class Mick {
private Map<MyEnum, OtherObj> myMap;
@Autowired
public void setMyMap(Map<MyEnum, OtherObj> myMap) {
this.myMap = myMap;
}
}
Regardez http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config
Mis à jour
Le problème est que, selon le schéma util, vous ne pouvez pas spécifier les types de clé ou de valeur. Vous pouvez cependant implémenter votre propre MapFactoryBean (héritez simplement de org.springframework.beans.factory.config.MapFactoryBean). One ceveat - remarquez que la définition générique (même les pensées effacées au moment de l'exécution) n'interfère pas.
L'élément <util:map>
a le type de clé, resp. attributs de type valeur, qui représente la classe des clés, resp. les valeurs. Si vous spécifiez la classe pleinement qualifiée de votre enum dans l'attribut key-type, les clés sont ensuite analysées dans cette enum lors de la création de la carte.
Spring vérifie lors de l'injection que les types de clé et de valeur de la carte - tels que déclarés dans la classe contenant la carte - sont compatibles avec les types de clé et de valeur du bean map. C'est en fait là que vous obtenez l'exception.
Vous avez juste besoin d'utiliser la classe Map
comme HashMap
et non d'abstraction ou d'interface
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() { .. }
}