• 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 ,所以其他源码略过
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    调用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;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    不含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,List等写法),有的话就直接返回
    			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);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    2、@Autowreid寻找依赖流程图

    在这里插入图片描述


    依赖注入完整流程图

    在这里插入图片描述

  • 相关阅读:
    商家团购app微信小程序模板
    Facebook:数字时代的文化交流平台
    《代码大全2》第7章 高质量的子程序
    Leetcode.2867 统计树中的合法路径数目
    数据库构建中的三范式设计(附SQL实例说明)
    ceph分布式存储
    c++中的cin和getline()函数
    基于JavaSwing开发简单的学生信息管理系统(增删改查SQLServer数据库)+报告
    Python数据类型
    解决JSON传参报错问题
  • 原文地址:https://blog.csdn.net/qq_33522097/article/details/128038323