spring源码-@Autowired、@Resource注解底层原理

这篇博客探讨了Spring框架中@Autowired和@Resource注解的底层工作原理。这两个注解在第六个后置处理器执行时解析,@Autowired注解会先尝试按类型,再按name查找bean,结合@Qualifier、@Primary和@Priority注解进行注入决策;而@Resource注解直接依据name从单例池中寻找匹配的bean进行注入。总结中强调了这两个注解在注入过程中的主要区别和逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上篇博客说了自动注入模型的使用,这篇笔记打算记录下自动注入模型中,autowireMode为0的情况,也就是我们经常用到的@Autowired、@Resource注解的原理

首先对于这两个注解,都是由后置处理器来完成解析的,解析的时机是一样的,在第六个后置处理器执行的时候;但是是由不同的后置处理器来完成解析的
@Autowired注解:

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues

@Resource注解:

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues

前言

1、这两个注解,都是在第六个后置处理器执行的时候,进行解析的,但是在第三个处理器

org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition

执行的时候,会先解析一下当前bean中有哪些属性要进行注入,在第六个后置处理器执行的时候,就无须进行解析,直接从map中获取要注入的属性即可

2、这两个注解虽然是由不同的后置处理器处理的,但是处理的思想、步骤大致都是一样的:

  1. 会先尝试获取bean中添加了该注解的方法(method)和属性(field)
  2. 找到之后,会根据实现类的优先级、或者是name等从容器中或者beanDefinitionMap中找到对应的属性
  3. 通过filed.set()完成属性的注入

3、这里有几个点要先行说明:

  • 对于@Resource注解,会根据要注入属性的name,从单实例池中获取bean,完成属性注入
  • 对于@Autowired注解,我们通常说是现根据类型注入,如果找到多个或者没有找到,再根据name进行注入;这里要说明的是:spring在解析@Autowired注解的时候,并不是直接从单实例池中查找bean,而是先从beanDefinitionMap中,根据type查找,如果找到多个,再根据name从单实例池中查找,只有找到确定要注入哪个类,才会从单实例池中找到对应的bean,完成注入
  • 当然,和@Autowired注解配合使用的注解有好几个,在下面会一一解析

@Autowired

在这里插入图片描述
这是@Autowired注解解析的整个流程,其中,和@Autowired注解配合使用的有几下几个注解:
@Qualifier
@Primary
@Priority

第一个注解使用在field上,在根据类型从beanDefinitionMap中找到bean之后,会判断哪个beanName是否是合格的;如果要注入的bean有多个实现类,会优先注入@Qualifier注解指定的实现类

第二个直接是在类上使用的,在未添加@Qualifier注解的场景下,如果有多个实现类,会判断哪个实现类上添加了@Primary注解,添加了,就注入该实现类

第三个注解也是加载类上,如果既没有添加@Qualifer、也没有添加@Priority注解,那么,会判断哪个实现类的优先级比较高,值越小,优先级越高

这是

org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

的部分代码

/**
 * @Autowired注解源码 三
 *  查找要注入的bean,按照type来查找,如果匹配到一个,就获取到这个实例,然后返回,返回之后,会调用field.set();注入进去
 *  如果找到了多个,那就先判断哪个实现类有@primary注解,如果都没有注解,那就判断priority的优先级
 *
 *  这个方法中,对Qualifier注解进行了处理;如果一个接口有多个实现类,但是没有加@Qualifier注解,那么就会返回多个
 *
 *  如果@Qualifier指定的value在spring容器中没有,这里返回的map集合就是空
 *
 */
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
   
	if (isRequired(descriptor)) {
   
		// 如果匹配到的要注入的bean是null,就报错
		raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
	}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值