定义了一个类:

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

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

  1. @Autowired
  2. SortedSet<String> message

就不行了。启动报错。

源码分析:

org.springframework.beans.factory.support.DefaultListableBeanFactory

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

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

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

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

结论:

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

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

Spring 注入集合类型的更多相关文章

  1. Spring 注入集合

    Spring 中,注入集合类型的数值方式 <bean id="javaCollection" class="com.qie_zi.JavaCollection&qu ...

  2. Ioc和Aop扩展--多种方式实现依赖注入(构造注入,p命名空间注入,集合类型注入,注入null和注入空值)

    构造注入 语法: <constructor-arg>    <ref bean="bean的id"/> </constructor-arg> 1 ...

  3. Spring中集合类型属性注入

    我们都知道如何去注入普通属性的值,非常简单,那么我们如何去注入开发中常见的集合类型的属性了,别急,往下看. 这里将介绍如何给Map list set Array Properties 这些属性注入值. ...

  4. Spring的DI(Ioc) - 注入集合类型

    1: 首先给service添加集合类型的属性,并提供getter, setter package cn.gbx.serviceimpl; import java.util.ArrayList; imp ...

  5. IoC容器-Bean管理XML方式(注入集合类型属性)

    Ico操作Bean管理(xml注入集合属性) 1,注入数组类型属性 2,注入List集合类型属性 3,注入Map集合类型属性 (1)创建类,定义数组.list.map.set类型属性,生成对应set方 ...

  6. spring注入对象类型的属性

    一.1.创建service类和Dao类 (1)在service中得到dao对象 2.具体实现过程 (1)在service里边把dao作为类型属性 (2)生成dao类型属性的set方法 public c ...

  7. Spring点滴八:Spring注入集合

    在Spring中我们通过value属性来配置基本数据类型,通过标签的ref属性来配置对象的引用.这两种情况只能给bean传递一个值,那么如何传递多个值呢?Spring提供了四种Collection类型 ...

  8. 【spring set注入 注入集合】 使用set注入的方式注入List集合和Map集合/将一个bean注入另一个Bean

    Dao层代码: package com.it.dao; public interface SayHell { public void sayHello(); } Dao的Impl实现层: packag ...

  9. spring集合类型的setter注入的一个简单例子

    在项目中我们有时候会为集合类型设定一些默认的值,使用spring后,我们可以通过配置文件的配置,用setter方式为对象的集合属性提供一些默认值,下面就是一个简单的例子. 首先我们创建了一个名为Col ...

随机推荐

  1. Pandas缺失数据处理

    Pandas缺失数据处理 Pandas用np.nan代表缺失数据 reindex() 可以修改 索引,会返回一个数据的副本: df1 = df.reindex(index=dates[0:4], co ...

  2. 疯狂JAVA——第七章 java基础类库

    System类代表当前java程序的运行平台,程序不能创建System类的对象,System类提供了一些类变量和类方法,允许直接通过System类来调用这些类变量和类方法.

  3. ldd3 源码相关问题参见

    参考地址: http://www.verydemo.com/demo_c92_i235635.html http://blog.csdn.net/silvervi/article/details/64 ...

  4. php去除bom

    <?php /*检测并清除BOM*/ if(isset($_GET['dir'])){ $basedir=$_GET['dir']; }else{ $basedir = '.'; } $auto ...

  5. X_PU

    通俗易懂告诉你CPU/GPU/TPU/NPU...XPU都是些什么鬼?[附把妹秘籍] 2017-10-27 19:54移动芯片/谷歌 作者:iot101君 物联网智库 原创 转载请注明来源和出处 现在 ...

  6. 支付宝SDK ios快捷支付

    配置PartnerConfig.h的参数 //合作身份者id,以2088开头的16位纯数字 #define PartnerID @"" //收款支付宝账号 #define Sell ...

  7. 跳跃游戏 12 · Jump Game 12

    跳跃游戏 1 [抄题]: [思维问题]: [一句话思路]: [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图]: [一刷]: 由于要用itera ...

  8. Java 架构师

    “学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 1.能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超 ...

  9. 提交代码到远程GIT仓库,代码自动同步到远程服务器上。

    现在一般都会通过github,gitlab,gitee来管理我们的代码.我们希望只要我本地push了代码,远程服务器能自动拉取git仓库的代码,进行同步. 这就需要用到各仓库为我们提供的webhook ...

  10. yii2中的rules 自定义验证规则详解

    yii2的一个强大之处之一就是他的Form组件,既方便又安全.有些小伙伴感觉用yii一段时间了,好嘛,除了比tp"难懂"好像啥都没有. 领导安排搞一个注册的功能,这家伙刷刷刷的又是 ...