@Autowired与@Resource源码区别

1、废话不多讲,直接干:

定位到

populateBean(beanName, mbd, instanceWrapper); 依赖注入的入口

2、主要看:PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					//依赖注入过程,@Autowired的支持
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}

						//老版本用这个完成依赖注入过程,@Autowired的支持
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}

3、这个方法就是对postprocessor接口的运用,查看其实现类,这两个类就是处理类,一个处理Autowired,一个处理Resource

 

 4、先看Autowired的吧

InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}

 第一行是从收集好的注解信息中,拿到注解信息,其实就是需要依赖注入的信息,再看 下面的方法

element.inject(target, beanName, pvs);

  

 

 我们只看属性的依赖注入,所以是选择第一个实现方法。

5、跟踪到这一段代码

try {
		value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}

6、再跟踪到这里

if (result == null) {
	result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}

 7、进去后里面有很多判断,@value的解析也在内,暂时不做分析,直接定位到这里

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
	if (matchingBeans.isEmpty()) {
		if (isRequired(descriptor)) {
			raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
		}
		return null;
	}

 意思是找到候选者bean,findAutowireCandidates()方法中是根据type来找到所有的beanName,也就是根据类型查找

如果候选者是空,那么说明确实没有找到对应的依赖bean,注入值是空,如果注解上没有标注可以注入为空标记,则抛异常。

8、下面就比较有意思了

if (matchingBeans.size() > 1)

  如果根据type找到不止一个bean,此时要另做判断,直接在代码后面做注释吧。

protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
		Class<?> requiredType = descriptor.getDependencyType();
		String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);寻找一个有@Primary注解的实现类作为依赖注入的类
		if (primaryCandidate != null) {
			return primaryCandidate;
		}
		String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);寻找一个有@Priority(2) 注解的实现类,并且取值最小的那一个。
if (priorityCandidate != null) {
return priorityCandidate;
} // Fallback                                               在下面没看懂,不做解释
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;
}

  如果以上都没判断出合格的bean则返回空。

9、最后else中是只有一个候选bean

else {
				// We have exactly one match.
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

 10、最后调用getBean操作

instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);

  总结一下:根据类型查找候选者,如果候选者为空,则注入一个空;如果是多个,查找最合适的那一个,都不合适返回空;如果

刚刚是一个,则调用getBean,返回bean。区别的话,等下一篇介绍@Resource后,自然而然就明白了。

 

 

  

posted @ 2021-07-27 17:42  0o飞行天下o0  阅读(81)  评论(0编辑  收藏  举报