Spring依赖注入源码解析(下)


前言

在上一篇文章Spring依赖注入源码解析(上)中,主要介绍了寻找注入点、以及注入源码分析


本章目标

这一篇主要源码解析在注入过程中,如何找到属性需要注入的依赖对象


resolveDependency—解决依赖查找

上篇文章有看到inject注入方法这里,调用到了resolveDependency方法,这个方法也在属性填充时,非常重要的核心源码之一,用于解决属性的解决依赖查找;

@Override
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
				Assert.state(beanFactory != null, "No BeanFactory available");
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {
					// 依赖查找,参数说明
					// desc:当前字段的 依赖描述对象
					// beanName:当前填充类的名称
					// typeConverter: spring内部常用的类型转换器
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				// ....这里主要解析resolveDependency ,所以其他源码略过

调用DefaultListableBeanFactory#resolveDependency

@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		// 看类型是不是Optional
		if (Optional.class == descriptor.getDependencyType()) {
			// 是的话则包装成Optional返回
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		// 是ObjectFactory或者ObjectProvider类
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			// 则直接创建一个ObjectFactory对象
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		// 判断是否为javax.inject.Provider
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			// 是的话则创建
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		// 日常开发基本都是走else这个逻辑
		else {
			// 判断有没有lazy注解
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				// 没有@Lazy注解,则调用doResolveDependency,真正处理依赖的方法
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

不含Lazy的时候为null,会直接会去执行doResolveDependency
在这里插入图片描述

属性orderService头上添加@Lazy注解后,不会进if,会直接返回代理对象
在这里插入图片描述


1、doResolveDependency

@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
		// 获取当前线程的缓存值,并且把当前依赖描述对象缓存起来
		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			// 默认实现返回Null
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}
			// 获取描述对象的类型
			Class<?> type = descriptor.getDependencyType();
			// 调用QualifierAnnotationAutowireCandidateResolver#getSuggestedValue方法,查看是否存在@Value注解
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				// 如果是String类型
				if (value instanceof String) {
					// 获取value内部内容值
					String strVal = resolveEmbeddedValue((String) value);
					// 获取beanName的Bean定义
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					// 获取value的内容,如解析表达式#{“xxx”} 、${"xxx"}等
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				// 获取类型转换器
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					// 根据属性的值转换为指定的类型
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}
			// 判断类型是不是数组、集合、map等(如Map<String,Intefate>,List<Intefate>等写法),有的话就直接返回
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}
			
			// 从beanDefinitionNames找到匹配的类型
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				// 如果是Required,并且没有找到就报错
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				// 不是Required,则返回null
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;
			// 如果有多个匹配属性
			if (matchingBeans.size() > 1) {
				// 这里会查看他是不是有@Primary 、@Priority,这里主要是处理优先级 
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					如果是Required,并且没有找到就报错
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						// 不是Required,则返回nul
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				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) {
				// 如果是一个class,则调佣getBean,生成bean
				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);
		}
	}

2、@Autowreid寻找依赖流程图

在这里插入图片描述


依赖注入完整流程图

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未闻花名丶丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值