面试突击78:@Autowired 和 @Resource 有什么区别?
@Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它。
@Autowired 和 @Resource 的区别主要体现在以下 5 点:
- 来源不同;
- 依赖查找的顺序不同;
- 支持的参数不同;
- 依赖注入的用法不同;
- 编译器 IDEA 的提示不同。
1.来源不同
@Autowired 和 @Resource 来自不同的“父类”,其中 @Autowired 是 Spring 定义的注解,而 @Resource 是 Java 定义的注解,它来自于 JSR-250(Java 250 规范提案)。
小知识:JSR 是 Java Specification Requests 的缩写,意思是“Java 规范提案”。任何人都可以提交 JSR 给 Java 官方,但只有最终确定的 JSR,才会以 JSR-XXX 的格式发布,如 JSR-250,而被发布的 JSR 就可以看作是 Java 语言的规范或标准。
2.依赖查找顺序不同
依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当前类中。而查找有分为两种实现:按名称(byName)查找或按类型(byType)查找,其中 @Autowired 和 @Resource 都是既使用了名称查找又使用了类型查找,但二者进行查找的顺序却截然相反。
2.1 @Autowired 查找顺序
@Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找,它的具体查找流程如下:

关于以上流程,可以通过查看 Spring 源码中的 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 实现分析得出,源码执行流程如下图所示:

2.2 @Resource 查找顺序
@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找,它的具体流程如下图所示:

关于以上流程可以在 Spring 源码的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中分析得出。虽然 @Resource 是 JSR-250 定义的,但是由 Spring 提供了具体实现,它的源码实现如下:

2.3 查找顺序小结
由上面的分析可以得出:
- @Autowired 先根据类型(byType)查找,如果存在多个(Bean)再根据名称(byName)进行查找;
- @Resource 先根据名称(byName)查找,如果(根据名称)查找不到,再根据类型(byType)进行查找。
3.支持的参数不同
@Autowired 和 @Resource 在使用时都可以设置参数,比如给 @Resource 注解设置 name 和 type 参数,实现代码如下:
@Resource(name = "userinfo", type = UserInfo.class)
private UserInfo user;
但二者支持的参数以及参数的个数完全不同,其中 @Autowired 只支持设置一个 required 的参数,而 @Resource 支持 7 个参数,支持的参数如下图所示:


4.依赖注入的支持不同
@Autowired 和 @Resource 支持依赖注入的用法不同,常见依赖注入有以下 3 种实现:
- 属性注入
- 构造方法注入
- Setter 注入
这 3 种实现注入的实现代码如下。
a) 属性注入
@RestController
public class UserController {
// 属性注入
@Autowired
private UserService userService;
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
b) 构造方法注入
@RestController
public class UserController {
// 构造方法注入
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
c) Setter 注入
@RestController
public class UserController {
// Setter 注入
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@RequestMapping("/add")
public UserInfo add(String username, String password) {
return userService.add(username, password);
}
}
其中, @Autowired 支持属性注入、构造方法注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入,当使用 @Resource 实现构造方法注入时就会提示以下错误:

5.编译器提示不同
当使用 IDEA 专业版在编写依赖注入的代码时,如果注入的是 Mapper 对象,那么使用 @Autowired 编译器会提示报错信息,报错内容如下图所示:

虽然 IDEA 会出现报错信息,但程序是可以正常执行的。
然后,我们再将依赖注入的注解更改为 @Resource 就不会出现报错信息了,具体实现如下:

总结
@Autowired 和 @Resource 都是用来实现依赖注入的注解(在 Spring/Spring Boot 项目中),但二者却有着 5 点不同:
- 来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250;
- 依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询;
- 支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数;
- 依赖注入的用法支持不同:@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入;
- 编译器 IDEA 的提示不同:当注入 Mapper 对象时,使用 @Autowired 注解编译器会提示错误,而使用 @Resource 注解则不会提示错误。
参考 & 鸣谢
- www.cnblogs.com/felordcn/p/13063802.html
- blog.csdn.net/CPLASF_/article/details/109225213
是非审之于己,毁誉听之于人,得失安之于数。
公众号:Java面试真题解析
面试突击78:@Autowired 和 @Resource 有什么区别?的更多相关文章
- @Autowired和@Resource注解的区别
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false.如果我们想使用按名称装配,可以结合@Qualifier注 ...
- Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理
一.spring依赖注入使用方式 @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byT ...
- @Autowired、@Resource、@Qualifier区别
@Autowired 1.属于spring的注解,如果不想和Spring耦合的太紧,就不推荐使用. 2.默认情况下,要求依赖对象必须存在,不能为null.如果允许为空,那么设置属性值required为 ...
- @Autowired 与@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下 ...
- java @Autowired与@Resource的区别
@Autowired与@Resource的区别 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认 ...
- Spring中@Autowired注解、@Resource注解的区别
Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...
- @Autowired与@Resource的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必 ...
- Spring 注释 @Autowired 和@Resource
一. @Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上. 二. @Autowired属于Spring的:@Resource为JSR-250标准的注释,属于J ...
- Spring 注释 @Autowired 和@Resource 的区别
Spring 注释 @Autowired 和@Resource 的区别 一. @Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上. 二. @Autowired ...
随机推荐
- C++ 炼气期之数据是主角
1. 前言 数据在程序中的重要性,怎么强调都不为过,程序的本质就是通过提供数据处理逻辑,把数据从一种状态变成另一种状态的过程.处理逻辑一定是有针对性的,针对的是数据本身的特性. 只有了解了数据本身的内 ...
- Python中的类变量和成员变量
类变量 定义 在类里面定义,且不位于构造或者成员函数里面,同时没有" self. " 的前缀:或者在类外定义,用 类名.类变量名 来新增加类变量. 使用 两种使用方法: (1)类名 ...
- jdk8对象集合转map集合
package koukay.Controller.Controllers; import koukay.Portal.webservices.Entity.User; import com.fast ...
- linux在线安装和配置JDK1.8
首先在服务器ping www.baidu.com查看是否可以连网 然后就可以在线下载 一.下载安装JDK1.8 1.在下载安装的同时做一些准备工作 我们在usr目录下再创建一个Java文件夹准备放置我 ...
- 手把手教你实现在Monaco Editor中使用VSCode主题
背景 笔者开源了一个小项目code-run,类似codepen的一个工具,其中代码编辑器使用的是微软的Monaco Editor,这个库是直接从VSCode的源码中生成的,只不过是做了一点修改让它支持 ...
- 如何用python做出老师看了都给满分的GUI学生管理系统毕设
序 言 哈喽大家好鸭!我是小熊猫 最近有什么有趣的事情发生吗?快来说给我听听( •̀ ω •́ )✧表弟大学快毕业了,学了一个学期Python居然还不会写学生管理系统,真的给我丢脸啊,教他又不肯学,还 ...
- gitlab和jenkins做持续集成构建教程
背景介绍 上一个轮回,我花了三篇文章的时间着重向大家介绍了在条件有限的情况下,如果优雅地进行前端发版和迭代.庆七一,热烈庆祝香港回归,人民生活水平越来越好,昨天上午我自掏腰包买了台服务器,决定由冷兵器 ...
- NC50528 滑动窗口
NC50528 滑动窗口 题目 题目描述 给一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,如下图: 你的任务是找出窗体在各个位置时的最大值 ...
- 面向个性化需求的在线云数据库混合调优系统 | SIGMOD 2022入选论文解读
SIGMOD 数据管理国际会议是数据库领域具有最高学术地位的国际性会议,位列数据库方向顶级会议之首.近日,腾讯云数据库团队的最新研究成果入选 SIGMOD 2022 Research Full Pap ...
- PTA(BasicLevel)-1023 组个最小数
一. 问题定义 给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位). 例如:给定两个 0,两个 1,三个 5,一个 8,我 ...