zoukankan      html  css  js  c++  java
  • spring bean的构造器参数

    spring组件的构造器参好神奇

    这里有一个接口: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,匹配成功但是没有数据,则会返回一个空对象。

  • 相关阅读:
    nodejs 教程
    文摘
    TED字幕摘抄
    Gamma函数相关matlab代码
    js以excel为模板的打印
    ASP.NET动态生成GridView的使用
    IE报错:缺少标识符、字符串或数字
    ExtJS Ext.Ajax.request最好设为同步
    javascript onclick 函数不执行
    Ext.grid.GridPanel数据转json
  • 原文地址:https://www.cnblogs.com/kobelieve/p/13236021.html
Copyright © 2011-2022 走看看