Spring 注入集合类型

编程技术  /  houtizong 发布于 3年前   52

最近有朋友问我如下问题:

我定义了一个类: 

@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的名字

 

 

 

 

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客