spring map使用annotation泛型注入问题分析



  今天在整一个spring的ioc学习demo,碰到一个问题,居然@Autowire在set方法注入map时,map的key类型不能为String之外的其他类型,具体看下面问题

  

  

	@Autowired
	public void setTypeMap(Map<Integer,String> typeMap) {
		this.typeMap = typeMap;
	}
 

  xml注入配置,即时在map上加上key和value的类型也不行。

  

      <property name="typeMap">
         <map key-type="java.lang.Integer" value-type="String">
            <entry key="1">
               <value>COO)</value>
            </entry>
            <entry key="2">
               <value>CFO</value>
            </entry>
            <entry key="3">
               <value>CEO</value>
            </entry>
         </map>
      </property>
 

  报错:

   

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springweb.service.impl.HelloServiceImpl.setTypeMap(java.util.Map); nested exception is org.springframework.beans.FatalBeanException: Key type [class java.lang.Integer] of map [java.util.Map] must be assignable to [java.lang.String]
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:589)
   at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
   ... 13 more
Caused by: org.springframework.beans.FatalBeanException: Key type [class java.lang.Integer] of map [java.util.Map] must be assignable to [java.lang.String]
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:761)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:547)
 

查看spring的代码

   

   else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
         Class keyType = descriptor.getMapKeyType();
         if (keyType == null || !String.class.isAssignableFrom(keyType)) {
            if (descriptor.isRequired()) {
               throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
                     "] must be assignable to [java.lang.String]");
            }
            return null;
         }
 

 

  也就是spring使用Autowired进入注入时,map的key类型只能为string,但是

   如果我使用set方法注入后者构造方法注入,map的可以是可以自动转为integer的。


   set方法注入,不要在set方法上使用antowired

   

	public void setTypeMap(Map<Integer,String> typeMap) {
		this.typeMap = typeMap;
	}
 

	//构造方法注入
	public HelloServiceImpl(String greetting,Map<Integer,String> typeMap){
		this.greetting = greetting;
		this.typeMap = typeMap;
		System.out.println("call HelloServiceImpl constructor" + this.greetting);
	}
  
<constructor-arg type="Map" index="1">
			<map>
				<entry key="1">
					<value>COO</value>
				</entry>
				<entry key="2">
					<value>CFO</value>
				</entry>
				<entry key="3">
					<value>CEO</value>
				</entry>
			</map>
		</constructor-arg>
 

   可以参考http://forum.springsource.org/showthread.php?105558-Autowired-injection-of-a-Map

  今天在整一个spring的ioc学习demo,碰到一个问题,居然@Autowire在set方法注入map时,map的key类型不能为String之外的其他类型,具体看下面问题

  

  

	@Autowired
	public void setTypeMap(Map<Integer,String> typeMap) {
		this.typeMap = typeMap;
	}
 

  xml注入配置,即时在map上加上key和value的类型也不行。

  

      <property name="typeMap">
         <map key-type="java.lang.Integer" value-type="String">
            <entry key="1">
               <value>COO)</value>
            </entry>
            <entry key="2">
               <value>CFO</value>
            </entry>
            <entry key="3">
               <value>CEO</value>
            </entry>
         </map>
      </property>
 

  报错:

   

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springweb.service.impl.HelloServiceImpl.setTypeMap(java.util.Map); nested exception is org.springframework.beans.FatalBeanException: Key type [class java.lang.Integer] of map [java.util.Map] must be assignable to [java.lang.String]
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:589)
   at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
   ... 13 more
Caused by: org.springframework.beans.FatalBeanException: Key type [class java.lang.Integer] of map [java.util.Map] must be assignable to [java.lang.String]
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:761)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:547)
 

查看spring的代码

   

   else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
         Class keyType = descriptor.getMapKeyType();
         if (keyType == null || !String.class.isAssignableFrom(keyType)) {
            if (descriptor.isRequired()) {
               throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
                     "] must be assignable to [java.lang.String]");
            }
            return null;
         }
 

 

  也就是spring使用Autowired进入注入时,map的key类型只能为string,但是

   如果我使用set方法注入后者构造方法注入,map的可以是可以自动转为integer的。


   set方法注入,不要在set方法上使用antowired

   

	public void setTypeMap(Map<Integer,String> typeMap) {
		this.typeMap = typeMap;
	}
 

	//构造方法注入
	public HelloServiceImpl(String greetting,Map<Integer,String> typeMap){
		this.greetting = greetting;
		this.typeMap = typeMap;
		System.out.println("call HelloServiceImpl constructor" + this.greetting);
	}
  
<constructor-arg type="Map" index="1">
			<map>
				<entry key="1">
					<value>COO</value>
				</entry>
				<entry key="2">
					<value>CFO</value>
				</entry>
				<entry key="3">
					<value>CEO</value>
				</entry>
			</map>
		</constructor-arg>
 

   可以参考http://forum.springsource.org/showthread.php?105558-Autowired-injection-of-a-Map

posted @ 2013-04-15 13:25  zhwj184  阅读(715)  评论(0编辑  收藏  举报