Spring框架:使用util:map填充Map

我有这个工厂类,我想通过spring连接地图的运行时配置。 地图包含枚举对象和标准pojo。

public class GenericEntityFactoryImpl implements GenericEntityFactory { private Map indexEntityMap = null; @Override public IEntity getIndexEntity(IndexType index) { return indexEntityMap.get(index); } public Map getIndexEntityMap() { return indexEntityMap; } public void setIndexEntityMap(Map indexEntityMap) { this.indexEntityMap = indexEntityMap; } } 

我在使用spring util时出现问题:地图布线,因为我不确定在确定键值时如何正确引用特定的枚举类型。 地图值的bean引用很容易。 所有spring地图布线的例子似乎都假设钥匙是一根绳子!

          

编辑

所以我重构了映射

        

但假设spring会很聪明……

 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添加到地图的每个枚举,我找到了一种解决方法 – 感谢创建spring-bean-from-java-5-enum

   CELL     APN   

定义了枚举,我可以在地图中对它们进行键控

         

这是另一种更短的格式:

       

确保包含命名空间

 xmlns:util="http://www.springframework.org/schema/util" 

和架构

 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd 

顺便说一下,我在这里使用Spring 3.0+

得到了和你一样的错误。 我能够通过将我的枚举移动到独立文件并使我的枚举公开来避免它。

所以我的

 public enum EventType { INFO, ERROR } 

放在

EventType.java

如果重要的话,我只有一个包。 我以这种方式注入依赖(通过构造函数arg通过xml):

spring.xml:

       

这对我来说是弹簧核心4.3.6

我相信有一个解释,这取决于reflection和内部Spring逻辑。 但我没有太多的Java经验,我无法提供。

我想这就是你需要的。 注意我认为您不需要指定键类型和值类型属性。 Spring应该能够解决这个问题。

         

您使用而不是clean annonomous

(参见第3.3.3.3节)的唯一原因是,如果您想将相同的地图连接到多个地方,或者您想使用不同的底层地图实现,例如ConcurrentHashMap。