0
点赞
收藏
分享

微信扫一扫

@Autowired依赖注入原理

犹大之窗 14小时前 阅读 1

spring中可以通过@Autowired注解注入依赖到bean的属性中,简单好用,但是出现多个类型相同的依赖,spring如何处理呢,现在开始了解下@Autowired注解处理依赖注入的原理。首先实例化之后,AutowiredAnnotationBeanPostProcessor处理器会找出存在@Autowired或@Value注解的字段,static不会处理,然后根据属性required判断是否需要注入。

// AutowiredAnnotationBeanPostProcessor
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				//找出使用了@Autowired或@Value注解的属性字段
				MergedAnnotation<?> ann = findAutowiredAnnotation(field);
				if (ann != null) {
					//static不处理,
					if (Modifier.isStatic(field.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
					//根据属性required判断是否需要注入
					boolean required = determineRequiredStatus(ann);
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

之后在postProcessProperties()方法中完成Bean的属性注入。逻辑到容器中根据类型找到要注入的bean,然后缓存下来,最后将找到的bean以反射写到属性。

// AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
		protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
                //优先从缓存中获取,可以根据beanName从Map<String, InjectionMetadata> injectionMetadataCache获取
                //再从AutowiredFieldElement中获取,这样可以防止重复创建相同的AutowiredFieldElement
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
......
                    //到容器中找到要注入的bean
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                    //缓存下来
......
							registerDependentBeans(beanName, autowiredBeanNames);
......
				}
			}
            //反射注入
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
				field.set(bean, value);
			}
		}

如果注入的类型是Optional,spring找到bean后会用Optional进行封装;如果注入的是ObjectFactoryObjectProvider则生成DependencyObjectProvider注入,之后再通过getObject获取实例;这些都不常见,用的最多的应该是正常的bean注入,先判断是否为存在@Lazy注解的懒加载模式,是的话就生成代理对象注入,之后getTarget获取真实的bean;都不是就进入正常的bean注入逻辑doResolveDependency

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

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

根据类型找到依赖的Bean是在doResolveDependency()方法中实现的,分两类考虑,如果是把bean注入到一个集合中就使用resolveMultipleBeans(),如果是单个bean的话就findAutowireCandidates(),当发现多个时需要在determineAutowireCandidate()进行处理,接下来就以注入单个bean为例看,因为开发中大部分都是注入单个bean的实例对象。

//  DefaultListableBeanFactory
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
		......//处理@Value注解
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		......
            //要注入多个bean到一个集合
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}
            // 注入单个bean
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			......

			String autowiredBeanName;
			Object instanceCandidate;
            //从多个bean中找到合适的bean
			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				......
				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();
			}

	}

protected Map<String, Object> findAutowireCandidates(
			@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
        //到容器中找到所需类型的bean的name集合
		String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this, requiredType, true, descriptor.isEager());
		Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
        //优先从缓存中根据依赖类型获取依赖的bean实例对象
		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;
				}
			}
		}
        //获取除自身外的其他bean
		for (String candidate : candidateNames) {
			if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
				addCandidateEntry(result, candidate, descriptor, requiredType);
			}
		}
		if (result.isEmpty()) {
......
			if (result.isEmpty() && !multiple) {
				// 没有获取到其他bean的话看看是不是注入自身
				for (String candidate : candidateNames) {
					if (isSelfReference(beanName, candidate) &&
							(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
							isAutowireCandidate(candidate, fallbackDescriptor)) {
						addCandidateEntry(result, candidate, descriptor, requiredType);
					}
				}
			}
		}
		return result;
	}

找到候选依赖后,需要决定注入的依赖。优先选择使用@Primary注解的bean,找不到的话根据@Priority注解选择,值越小优先级越高,否则根据name匹配,即根据字段名选择名字相同的依赖bean。

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
		Class<?> requiredType = descriptor.getDependencyType();
        //优先使用@Primary注解的bean
		String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
		if (primaryCandidate != null) {
			return primaryCandidate;
		}
        //@Priority注解的值越小优先级越高
		String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
		if (priorityCandidate != null) {
			return priorityCandidate;
		}
		//根据bean的name进行匹配
		for (Map.Entry<String, Object> entry : candidates.entrySet()) {
			String candidateName = entry.getKey();
			Object beanInstance = entry.getValue();
			if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
					matchesBeanName(candidateName, descriptor.getDependencyName())) {
				return candidateName;
			}
		}
		return null;
	}

举报

相关推荐

0 条评论