肥宅兜

导航

Spring 注入集合类型

定义了一个类: 

Java代码  收藏代码
  1. @Service   
  2. public class StringTest implements CachedRowSet,SortedSet<String>,Cloneable   
Java代码  收藏代码
  1. @Controller   
  2. public class HomeController {   
  3. @Autowired   
  4. CachedRowSet message;   
  5.   
  6. @Autowired   
  7. CachedRowSet message1;   
  8. }   

 这里CachedRowSet , 等其他接口都是可以注入的,包括StringTest  也行。 
但是使用: 

Java代码  收藏代码
  1. @Autowired   
  2. SortedSet<String> message  

 就不行了。启动报错。 

 

源码分析:

org.springframework.beans.factory.support.DefaultListableBeanFactory

Java代码  收藏代码
  1. protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName,  
  2.         Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {  
  3.   
  4.     Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);  
  5.     if (value != null) {  
  6.         if (value instanceof String) {  
  7.             String strVal = resolveEmbeddedValue((String) value);  
  8.             BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);  
  9.             value = evaluateBeanDefinitionString(strVal, bd);  
  10.         }  
  11.         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
  12.         return (descriptor.getField() != null ?  
  13.                 converter.convertIfNecessary(value, type, descriptor.getField()) :  
  14.                 converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));  
  15.     }  
  16.   
  17.     if (type.isArray()) {  
  18.         Class<?> componentType = type.getComponentType();  
  19.         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);  
  20.         if (matchingBeans.isEmpty()) {  
  21.             if (descriptor.isRequired()) {  
  22.                 raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);  
  23.             }  
  24.             return null;  
  25.         }  
  26.         if (autowiredBeanNames != null) {  
  27.             autowiredBeanNames.addAll(matchingBeans.keySet());  
  28.         }  
  29.         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
  30.         return converter.convertIfNecessary(matchingBeans.values(), type);  
  31.     }  
  32.     else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {  
  33.         Class<?> elementType = descriptor.getCollectionType();  
  34.         if (elementType == null) {  
  35.             if (descriptor.isRequired()) {  
  36.                 throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");  
  37.             }  
  38.             return null;  
  39.         }  
  40.         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);  
  41.         if (matchingBeans.isEmpty()) {  
  42.             if (descriptor.isRequired()) {  
  43.                 raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);  
  44.             }  
  45.             return null;  
  46.         }  
  47.         if (autowiredBeanNames != null) {  
  48.             autowiredBeanNames.addAll(matchingBeans.keySet());  
  49.         }  
  50.         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
  51.         return converter.convertIfNecessary(matchingBeans.values(), type);  
  52.     }  
  53.     else if (Map.class.isAssignableFrom(type) && type.isInterface()) {  
  54.         Class<?> keyType = descriptor.getMapKeyType();  
  55.         if (keyType == null || !String.class.isAssignableFrom(keyType)) {  
  56.             if (descriptor.isRequired()) {  
  57.                 throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +  
  58.                         "] must be assignable to [java.lang.String]");  
  59.             }  
  60.             return null;  
  61.         }  
  62.         Class<?> valueType = descriptor.getMapValueType();  
  63.         if (valueType == null) {  
  64.             if (descriptor.isRequired()) {  
  65.                 throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");  
  66.             }  
  67.             return null;  
  68.         }  
  69.         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);  
  70.         if (matchingBeans.isEmpty()) {  
  71.             if (descriptor.isRequired()) {  
  72.                 raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);  
  73.             }  
  74.             return null;  
  75.         }  
  76.         if (autowiredBeanNames != null) {  
  77.             autowiredBeanNames.addAll(matchingBeans.keySet());  
  78.         }  
  79.         return matchingBeans;  
  80.     }  
  81.     else {  
  82.         Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);  
  83.         if (matchingBeans.isEmpty()) {  
  84.             if (descriptor.isRequired()) {  
  85.                 raiseNoSuchBeanDefinitionException(type, "", descriptor);  
  86.             }  
  87.             return null;  
  88.         }  
  89.         if (matchingBeans.size() > 1) {  
  90.             String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);  
  91.             if (primaryBeanName == null) {  
  92.                 throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());  
  93.             }  
  94.             if (autowiredBeanNames != null) {  
  95.                 autowiredBeanNames.add(primaryBeanName);  
  96.             }  
  97.             return matchingBeans.get(primaryBeanName);  
  98.         }  
  99.         // We have exactly one match.  
  100.         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();  
  101.         if (autowiredBeanNames != null) {  
  102.             autowiredBeanNames.add(entry.getKey());  
  103.         }  
  104.         return entry.getValue();  
  105.     }  
  106. }  

 

从上边的源码大家可以看出:

1、首先判断注入的类型,如果是数组、Collection、Map,则注入的是元素数据,即查找与元素类型相同的Bean的注入到集合,而不是找跟集合类型相同的

 

2、对于Map,key只能是String类型,而且默认是Bean的名字

 

结论:

1、对于数组、集合、Map,注入的元素类型,如SortedSet<String> 其实是找所有String类型的Bean注入到集合

2、Map,key只能是String类型,而且默认是Bean的名字

 

posted on 2016-08-19 22:40  肥宅兜  阅读(1052)  评论(0编辑  收藏  举报