2023-09-16  阅读(207)
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105093344

DefaultListableBeanFactory的doResolveDependency解析依赖

继续上篇的,如果是我们自己定义的类型的参数,没有懒加载注解的,就会进行解析。
首先看BeanFactiry是否有添加快捷方式,一般没有,除非子类继承扩展,然后看是否有注解方法设置的参数的值,有的话就设置处理。否则的话就判断是否是多个bean的注入,比如参数类型是集合。最后才是获取自动装配类型的对象findAutowireCandidates,如果找到多个的话,会进行优先级来选取,然后进行装配类型对象的创建,这里的创建又是一个getBean的过程,但是也可能是直接获取,一般来说是主要看工厂方法的定义顺序,因为内部可以用了ASM处理,但是如果有重名的,就乱序了,具体为什么不行可以看ConfigurationClassParserretrieveBeanMethodMetadata方法,不过影响也不大,反正都能自动装配好。创建好了再判断类型是否匹配,最后返回。下面我们来分析几个主要的方法,主要的理解了,其他的自己慢慢了解就行。

    	@Nullable
    	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
    			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    		//设置注入点,并获得前一个注入点,以便后面可以设置回来
    		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    		try {//解析快捷方式,存在就返回,子类BeanFactiry可以扩展,默认null
    			Object shortcut = descriptor.resolveShortcut(this);
    			if (shortcut != null) {
    				return shortcut;
    			}
    
    			Class<?> type = descriptor.getDependencyType();
    			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());
    				try {
    					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
    				}
    				catch (UnsupportedOperationException ex) {
    					// A custom TypeConverter which does not support TypeDescriptor resolution...
    					return (descriptor.getField() != null ?
    							converter.convertIfNecessary(value, type, descriptor.getField()) :
    							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
    				}
    			}
    			//是否是多个bean的注入,比如参数类型是集合,map
    			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
    			if (multipleBeans != null) {
    				return multipleBeans;
    			}
    			//寻找装配候选对象
    			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    			if (matchingBeans.isEmpty()) {
    				if (isRequired(descriptor)) {//空的话,又是必须的,才会报异常
    					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    				}
    				return null;
    			}
    
    			String autowiredBeanName;//自动装配的bean名字
    			Object instanceCandidate;//装配实例
    
    			if (matchingBeans.size() > 1) {//有多个
    				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    				if (autowiredBeanName == null) {
    					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
    						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
    					}
    					else {
    
    						return null;
    					}
    				}
    				instanceCandidate = matchingBeans.get(autowiredBeanName);
    			}
    			else {//只有一个
    				// We have exactly one match.
    				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
    				autowiredBeanName = entry.getKey();
    				instanceCandidate = entry.getValue();
    			}
    
    			if (autowiredBeanNames != null) {
    				autowiredBeanNames.add(autowiredBeanName);
    			}
    			if (instanceCandidate instanceof Class) {//获取装配实例,也要进行getBean过程
    				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    			}
    			Object result = instanceCandidate;
    			if (result instanceof NullBean) {
    				if (isRequired(descriptor)) {//不存在,又是必须
    					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    				}
    				result = null;
    			}
    			if (!ClassUtils.isAssignableValue(type, result)) {//类型不匹配
    				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
    			}
    			return result;
    		}
    		finally {//处理完后恢复当前注入点
    			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    		}
    	}

DefaultListableBeanFactory的findAutowireCandidates寻找自动装配类型

这里会去寻找我们的容器里面是否有参数的类型,先把参数类型的bean定义中的所有bean名字找出来,创建一个LinkedHashMap集合,然后判断类型是不是内部的类型,是的话也要加进去。然后遍历候选名字集合,把非自引用的可以作为别人依赖的类型添加到集合中,如果集合为空,还要进行处理判断,比如是不是数组类型,集合类型,再做相应处理。

    protected Map<String, Object> findAutowireCandidates(
    			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
    		//获取requiredType对应的bean名字数组
    		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
    				this, requiredType, true, descriptor.isEager());
    		Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
    		for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {//如果是依赖内部一些类的类型
    			Class<?> autowiringType = classObjectEntry.getKey();
    			if (autowiringType.isAssignableFrom(requiredType)) {
    				Object autowiringValue = classObjectEntry.getValue();
    				autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
    				if (requiredType.isInstance(autowiringValue)) {
    					result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
    					break;
    				}
    			}
    		}
    		for (String candidate : candidateNames) {//自定义的基本在这里
    			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
    				addCandidateEntry(result, candidate, descriptor, requiredType);//非自引用,且可以为其他类做自动装配的,就加入集合
    			}
    		}
    		if (result.isEmpty()) {//空的处理
    			boolean multiple = indicatesMultipleBeans(requiredType);
    			// Consider fallback matches if the first pass failed to find anything...
    			DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
    			for (String candidate : candidateNames) {
    				if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
    						(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
    					addCandidateEntry(result, candidate, descriptor, requiredType);
    				}
    			}
    			if (result.isEmpty() && !multiple) {
    				// Consider self references as a final pass...
    				// but in the case of a dependency collection, not the very same bean itself.
    				for (String candidate : candidateNames) {
    					if (isSelfReference(beanName, candidate) &&
    							(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
    							isAutowireCandidate(candidate, fallbackDescriptor)) {
    						addCandidateEntry(result, candidate, descriptor, requiredType);
    					}
    				}
    			}
    		}
    		return result;
    	}

addCandidateEntry添加到候选集合里

如果是多元素集合和StreamDependencyDescriptor类型的,会去创建相应的bean,然后放入,否则就直接把类型放入进来。

    private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
    			DependencyDescriptor descriptor, Class<?> requiredType) {
    
    		if (descriptor instanceof MultiElementDescriptor) {
    			Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
    			if (!(beanInstance instanceof NullBean)) {
    				candidates.put(candidateName, beanInstance);
    			}
    		}
    		else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
    				((StreamDependencyDescriptor) descriptor).isOrdered())) {
    			Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
    			candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
    		}
    		else {
    			candidates.put(candidateName, getType(candidateName));
    		}
    	}

DependencyDescriptor的resolveCandidate

当我们解析出来要装配的类型的时候,就可以开始去真正的获取该类型的对象了,其实内部还是调用getBean的。

    	public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
    			throws BeansException {
    
    		return beanFactory.getBean(beanName);
    	}

大致的流程就分析到这里啦,很多细节还没深入,因为比较复杂,还是先把大致搞清楚在去琢磨细节比较好。下篇我们把基本的流程图总计下。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

阅读全文
  • 点赞