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];
文章归档
文章标签
友情链接