最近有朋友问我如下问题:
我定义了一个类:
@Service public class StringTest implements CachedRowSet,SortedSet<String>,Cloneable
@Controller public class HomeController { @Autowired CachedRowSet message; @Autowired CachedRowSet message1; }
这里CachedRowSet , 等其他接口都是可以注入的,包括StringTest 也行。
但是使用:
@Autowired SortedSet<String> message
就不行了。启动报错。
源码分析:
org.springframework.beans.factory.support.DefaultListableBeanFactory
protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } if (type.isArray()) { Class<?> componentType = type.getComponentType(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return converter.convertIfNecessary(matchingBeans.values(), type); } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getCollectionType(); if (elementType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); } return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return converter.convertIfNecessary(matchingBeans.values(), type); } 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; } Class<?> valueType = descriptor.getMapValueType(); if (valueType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); } return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(type, "", descriptor); } return null; } if (matchingBeans.size() > 1) { String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor); if (primaryBeanName == null) { throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet()); } if (autowiredBeanNames != null) { autowiredBeanNames.add(primaryBeanName); } return matchingBeans.get(primaryBeanName); } // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); if (autowiredBeanNames != null) { autowiredBeanNames.add(entry.getKey()); } return entry.getValue(); } }
从上边的源码大家可以看出:
1、首先判断注入的类型,如果是数组、Collection、Map,则注入的是元素数据,即查找与元素类型相同的Bean的注入到集合,而不是找跟集合类型相同的
2、对于Map,key只能是String类型,而且默认是Bean的名字
结论:
1、对于数组、集合、Map,注入的元素类型,如SortedSet<String> 其实是找所有String类型的Bean注入到集合
2、Map,key只能是String类型,而且默认是Bean的名字
相关推荐
1.1 收集方式 1.2 直接装配方式 2.1 收集装配 2.2 直接装配方式
在Spring框架中,集合类型的装配是一项重要的功能,它允许我们把多个同类型的bean注入到一个集合对象中,如List、Set、Map等。这在处理依赖关系时非常有用,特别是当我们需要管理一组相似对象或者需要根据配置动态...
在Spring框架中,集合装配是将一组对象注入到如List、Set、Map等集合类型属性中的过程。这个过程是依赖注入(Dependency Injection,DI)的一个重要方面,它使得应用程序更加灵活,易于测试和维护。本篇文章将深入...
Spring支持对List、Set、Map等集合类型的注入。例如,你可以声明一个Bean,其属性是一个List,并在配置文件或使用Java配置类时提供具体的元素值。这使得在运行时,Spring会自动创建对应的集合并填充数据。 2. ...
Spring4对注入参数的支持更加完善,本章将深入探讨Spring4中的参数注入机制,包括基本类型注入、对象注入、集合类型注入以及如何通过注解实现这些功能。 一、基本类型注入 Spring4允许我们将基本数据类型(如int、...
集合注入允许我们在Spring配置中将一组对象注入到单个bean属性中,这些对象通常以集合类型(如List、Set、Map等)存在。这样做的好处是可以方便地管理多个依赖项,而无需为每个依赖项创建单独的bean。 例如,假设...
4. **集合类型的注入**:对于List、Set、Map等集合类型,Spring可以批量注入多个值。在XML配置中,你可以使用`<list>`、`<set>`或`<map>`标签来定义这些集合,并提供多个子元素。在Java配置中,可以使用`@Autowired`...
在Spring框架中,集合属性(Collections Property)是一个重要的概念,它允许我们配置bean的属性为集合类型,如List、Set、Map等。这些集合可以由Spring容器动态填充,提供了极大的灵活性和可配置性,使得我们可以...
设值注入不仅限于字符串,还可以注入其他类型的值,如基本类型、集合、其他bean引用等。例如,你可以注入一个列表: ```xml <value>1 <value>2 <value>3 ``` 或者,使用SpEL(Spring Expression ...
2. **XML中的Map集合注入** 当我们需要注入一个Map时,Spring提供了特殊的`<map>`标签。不同于其他标签,`<entry>`子标签用于定义键值对: ```xml ``` 在这个例子中,`myBean`的`myMap`属性...
此外,Spring4还支持对集合类型的自动装配,如List、Set、Map等。 为了更好地实践这些概念,我们可以查看压缩包中的Spring0501文件,这可能包含了示例代码或教程资源。通过实际操作和调试,你可以更深入地理解和...
5. **属性注入**:除了基本类型的属性外,Spring还能处理复杂类型的属性注入,如集合(List、Set、Map等)、自定义对象等。对于集合,可以通过`@Resource`或`@Autowired`注解配合`@Value`来注入值,对于自定义对象,...
7. `spring-aop.xml`: 用于配置Spring的AOP(面向切面编程)相关设置,如定义切面、通知类型等,使得我们可以进行横切关注点的处理,如日志记录、事务管理等。 8. `log4j.xml`: 该文件是Log4j的日志配置,定义了...
装配bean——集合类型注入值: 本文介绍数组、list集合、set集合、map集合、properties的注值 博客原文地址:http://blog.csdn.net/tingzhiyi/article/details/52104203
在本主题“day38 14-Spring的Bean的属性的注入:集合属性的注入”中,我们将深入探讨如何向Bean注入集合类型的属性,如List、Set、Map等。这在实际开发中非常常见,因为很多情况下我们需要处理一组相关的数据。 ...
Spring的依赖注入不仅限于bean之间的关系,还可以用于注入集合类型,如List、Set、Map等,甚至可以处理复杂类型的依赖注入,如接口类型的多实现。 在`chapter8`这个文件夹中,可能包含了关于Spring依赖注入的深入...
本文档主要介绍了在Spring配置文件中如何进行各种类型的属性注入,包括基本类型、集合类型以及Bean之间的引用等。下面将逐一展开介绍每种注入方式的细节及其应用场景。 #### 基本类型属性注入 基本类型的属性注入...
本文将深入探讨如何在Spring中通过XML配置文件对Bean进行值的注入,包括List、Set和Map等集合类型的注入。 首先,我们需要了解Spring Bean的定义。在Spring中,Bean是一个被Spring容器管理的对象,它可以通过XML、...
在Spring框架的学习中,"装配各种集合类型的属性"是一个重要的概念,这涉及到如何将不同的集合对象,如List、Set、Map等,与Spring的依赖注入(Dependency Injection, DI)机制相结合,实现灵活的配置和管理。...