Spring框架:填充地图< Enum,Object> with util:map [英] Spring Framework : Populating a Map<Enum,Object> with util:map
问题描述
我有这个工厂类,我想通过spring连接到地图的运行时配置。地图包含枚举对象和标准pojo。
I have this factory class, which i want to wire via spring for runtime configuration of the map. The map contains an enum object and standard pojo.
public class GenericEntityFactoryImpl implements GenericEntityFactory
{
private Map<IndexType,IEntity> indexEntityMap = null;
@Override
public IEntity getIndexEntity(IndexType index) {
return indexEntityMap.get(index);
}
public Map<IndexType, IEntity> getIndexEntityMap() {
return indexEntityMap;
}
public void setIndexEntityMap(Map<IndexType, IEntity> indexEntityMap) {
this.indexEntityMap = indexEntityMap;
}
}
我的spring util有问题:地图接线,因为我不确定在确定键值时如何正确引用特定的枚举类型。地图值的bean引用很容易。弹簧图布线的所有示例似乎都假设键是一个字符串!
I'm having trouble with my spring util:map wiring, since i'm not sure how to correctly reference a specific enum type when definiting the key value. The bean ref for the map value is easy. All the examples of spring map wiring seem to assume that the key is a string!
<!-- the value object bean -->
<bean id="cell" class="com.xx.xx.common.index.entity.CellEntity"/>
<bean id="genericEntityFactory" class="com.xx.xx.common.index.GenericEntityFactoryImpl">
<util:map
id="indexEntityMap"
map-class="java.util.HashMap"
key-type="com.xx.xx.common.index.IndexType"
value-type="com.xx.xx.common.index.GenericEntityFactoryImpl">
<entry key="CELL">
<ref bean="cell"/>
</entry>
</util:map>
</bean>
编辑
所以我重构了映射
<bean id="genericEntityFactory" class="com.xx.xx.common.index.GenericEntityFactoryImpl" >
<property name="indexEntityMap">
<map >
<entry key="com.xx.xx.common.index.CELL"><ref bean="cell"/></entry>
</map>
</property>
</bean>
但假设春天将是智能失败......
but assumption that spring will be smart fails...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'genericEntityFactory' defined in class path resource [com/xx/xx/common/index/index-application-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.LinkedHashMap] to required type [java.util.Map] for property 'indexEntityMap'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.xx.xx.common.index.IndexType] for property 'indexEntityMap[com.xx.xx.common.index.CELL]': no matching editors or conversion strategy found
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:42)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:173)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:197)
... 17 more
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.util.LinkedHashMap] to required type [java.util.Map] for property 'indexEntityMap'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.xx.xx.common.index.IndexType] for property 'indexEntityMap[com.xx.xx.common.index.CELL]': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:391)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1249)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
... 32 more
Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.xx.xx.common.index.IndexType] for property 'indexEntityMap[com.xx.xx.common.index.CELL]': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:219)
at org.springframework.beans.TypeConverterDelegate.convertToTypedMap(TypeConverterDelegate.java:508)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:194)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
... 36 more
推荐答案
我找到了一个解决方法,通过定义我计划作为单独的bean添加到地图的每个枚举 - 感谢 creation-spring-bean-from-java-5-enum
I found a workaround by defining each enum I plan to add to the map as a separate bean - thanks to creating-spring-bean-from-java-5-enum
<bean id="CELL" class="com.xx.xx.common.index.IndexType" factory-method="valueOf">
<constructor-arg>
<value>CELL</value>
</constructor-arg>
</bean>
<bean id="APN" class="com.xx.xx.common.index.IndexType" factory-method="valueOf">
<constructor-arg>
<value>APN</value>
</constructor-arg>
</bean>
定义了枚举,我可以在地图中对它们进行密钥修改
Having defined the enums I can them key-ref them in the map
<bean id="genericEntityFactory" class="com.xx.xx.common.index.GenericEntityFactoryImpl" >
<property name="indexEntityMap">
<map>
<entry key-ref="CELL"><ref bean="cell"/></entry>
<entry key-ref="APN"><ref bean="apn"/></entry>
</map>
</property>
</bean>
这篇关于Spring框架:填充地图< Enum,Object> with util:map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!