代码之家  ›  专栏  ›  技术社区  ›  emeraldjava

Spring框架:用实用程序:映射

  •  14
  • emeraldjava  · 技术社区  · 16 年前

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

    我的弹簧有问题实用程序:地图布线,因为我不确定在定义键值时如何正确引用特定的枚举类型。映射值的bean引用很简单。所有SpringMap连接的示例似乎都假设键是一个字符串!

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

    但是,假设春天是聪明的失败了。。。

    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
    
    4 回复  |  直到 13 年前
        1
  •  12
  •   emeraldjava    10 年前

    我找到了一个解决方法,将我计划添加到映射中的每个枚举定义为一个单独的bean—多亏了 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>
    

    定义了枚举之后,我可以在地图中对它们进行键引用

    <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>
    
        2
  •  10
  •   Betlista    13 年前

    以下是另一种较短的格式:

    <bean id="versionService" class="my.service.VersionService" 
            p:animalDAOMap-ref="animalDAOMap"/>
    
    <util:map id="p:animalDAOMap">
        <entry key="chicken" value-ref="chickenDAO"/>
        <entry key="monkey" value-ref="monkeyDAO"/>
        <entry key="pig" value-ref="pigDAO"/>
    </util:map>
    

    确保包含命名空间

    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
    

    顺便说一下,我在这里使用的是Spring3.0+

        3
  •  0
  •   Mosolov Sergey    9 年前

    和你犯了同样的错误。我可以通过将枚举移到独立文件并公开枚举来避免它。

    所以我的

    public enum EventType { INFO, ERROR }
    

    放置在

    事件类型.java

    而且我只有一个包裹,如果这有什么关系的话。 我以这种方式(通过构造函数arg的xml)注入依赖关系:

    <constructor-arg>
        <map>
            <entry key="INFO" value-ref="consoleEventLogger"></entry>
            <entry key="ERROR" value-ref="combinedEventLogger"></entry>
        </map>
    </constructor-arg>
    

    我用的是SpringCore4.3.6

    我相信有一种解释,那取决于反思和内在的弹簧逻辑。但是我没有太多的Java经验,我不能提供这些。

        4
  •  -1
  •   mR_fr0g    16 年前

    <bean id="genericEntityFactory" class="com.xx.xx.common.index.GenericEntityFactoryImpl">
      <property name="indexEntityMap" ref="indexEntityMapBean"/>
    </bean>
    
    <util:map id="indexEntityMapBean" 
           map-class="java.util.HashMap" 
           key-type="com.xx.xx.common.index.IndexType" 
           value-type="com.xx.xx.common.index.GenericEntityFactoryImpl">
               <entry key="com.xx.xx.common.index.IndexType.CELL">
                    <ref bean="cell"/>
               </entry>
    </util:map>
    

    你用 <util:map 而不是更干净的注释 <map> (见第节) 3.3.3.3 )如果您想将同一个映射连接到多个地方,或者您想使用不同的基础映射实现,例如ConcurrentHashMap。