itjavashuai 2020-07-04
这里有一个接口:FruitService和两个实现类:AppleService、BananaService,假设我想在其中一个实现类实例化中获取当前Spring容器的Bean怎么办?
只需要重写该实现类的构造方法:
@Component public class AppleService implements FruitService { public AppleService(List<Object> list) { System.out.println(list); } }
list可以获取当前spring实例化好的Beans:
我能不能只拿某个Bean呢,答案是可以的,只需要重写将Objent替换成对应的类即可:
@Component public class AppleService implements FruitService { public AppleService(List<FruitService> list) { System.out.println(list); } }
不仅如此,还可以将参数转换成Map和Collection类型,spring也会自动帮忙处理,但是如果是非上述类型,则会在创建的时候抛出异常。
由于spring源码非常深,这里直接列出处理这个人性化的地方最核心一个方法:org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans
@Nullable private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) { final Class<?> type = descriptor.getDependencyType(); if (descriptor instanceof StreamDependencyDescriptor) { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } Stream<Object> stream = matchingBeans.keySet().stream() .map(name -> descriptor.resolveCandidate(name, type, this)) .filter(bean -> !(bean instanceof NullBean)); if (((StreamDependencyDescriptor) descriptor).isOrdered()) { stream = stream.sorted(adaptOrderComparator(matchingBeans)); } return stream; } else if (type.isArray()) { Class<?> componentType = type.getComponentType(); ResolvableType resolvableType = descriptor.getResolvableType(); Class<?> resolvedArrayType = resolvableType.resolve(type); if (resolvedArrayType != type) { componentType = resolvableType.getComponentType().resolve(); } if (componentType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType); if (result instanceof Object[]) { Comparator<Object> comparator = adaptDependencyComparator(matchingBeans); if (comparator != null) { Arrays.sort((Object[]) result, comparator); } } return result; } else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); if (elementType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (result instanceof List) { if (((List<?>) result).size() > 1) { Comparator<Object> comparator = adaptDependencyComparator(matchingBeans); if (comparator != null) { ((List<?>) result).sort(comparator); } } } return result; } else if (Map.class == type) { ResolvableType mapType = descriptor.getResolvableType().asMap(); Class<?> keyType = mapType.resolveGeneric(0); if (String.class != keyType) { return null; } Class<?> valueType = mapType.resolveGeneric(1); if (valueType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { return null; } }
spring会一一匹配指定类型,假如没有匹配成功,则会返回null,匹配成功但是没有数据,则会返回一个空对象。