zoukankan      html  css  js  c++  java
  • 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的名字

  • 相关阅读:
    Ubuntu下建立Android开发环境
    c#值类型和引用类型
    Jude Begin
    Eclipse C/C++ development environment creation
    C# var usage from MSDN
    SubSonic应用_Collection
    C#2.0中委托与匿名委托引
    sql语句的执行步骤——zhuan
    图˙谱˙马尔科夫过程·聚类结构 (转载,原始出处不详)
    Hadoop集群新增节点实现方案
  • 原文地址:https://www.cnblogs.com/doudouxiaoye/p/5789299.html
Copyright © 2011-2022 走看看