首页 > 其他分享 >面试突击78:@Autowired 和 @Resource 有什么区别?

面试突击78:@Autowired 和 @Resource 有什么区别?

时间:2022-08-29 08:44:31浏览次数:92  
标签:Resource Autowired Spring 查找 userService 注入 78

@Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它。
@Autowired 和 @Resource 的区别主要体现在以下 5 点:

  1. 来源不同;
  2. 依赖查找的顺序不同;
  3. 支持的参数不同;
  4. 依赖注入的用法不同;
  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)进行查找,它的具体查找流程如下:
image.png
关于以上流程,可以通过查看 Spring 源码中的 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 实现分析得出,源码执行流程如下图所示:
image.png

2.2 @Resource 查找顺序

@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找,它的具体流程如下图所示:
image.png
关于以上流程可以在 Spring 源码的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中分析得出。虽然 @Resource 是 JSR-250 定义的,但是由 Spring 提供了具体实现,它的源码实现如下:
image.png

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 个参数,支持的参数如下图所示:
image.png
image.png

4.依赖注入的支持不同

@Autowired 和 @Resource 支持依赖注入的用法不同,常见依赖注入有以下 3 种实现:

  1. 属性注入
  2. 构造方法注入
  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 实现构造方法注入时就会提示以下错误:
image.png

5.编译器提示不同

当使用 IDEA 专业版在编写依赖注入的代码时,如果注入的是 Mapper 对象,那么使用 @Autowired 编译器会提示报错信息,报错内容如下图所示:
image.png
虽然 IDEA 会出现报错信息,但程序是可以正常执行的。
然后,我们再将依赖注入的注解更改为 @Resource 就不会出现报错信息了,具体实现如下:
image.png

总结

@Autowired 和 @Resource 都是用来实现依赖注入的注解(在 Spring/Spring Boot 项目中),但二者却有着 5 点不同:

  1. 来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250;
  2. 依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询;
  3. 支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数;
  4. 依赖注入的用法支持不同:@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入;
  5. 编译器 IDEA 的提示不同:当注入 Mapper 对象时,使用 @Autowired 注解编译器会提示错误,而使用 @Resource 注解则不会提示错误。

参考 & 鸣谢

  • www.cnblogs.com/felordcn/p/13063802.html
  • blog.csdn.net/CPLASF_/article/details/109225213

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java面试真题解析

面试合集:https://gitee.com/mydb/interview

标签:Resource,Autowired,Spring,查找,userService,注入,78
From: https://www.cnblogs.com/vipstone/p/16634716.html

相关文章

  • Spring 高级 @Autowired 失效分析
    一、失效演示1、正常情况packagecom.mangoubiubiu.show.a06;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;......
  • Spring @Autowired 注解静态变量
    最近应该项目的需要,需要使用一个工具类来访问数据库。但是这个工具类又被定义成静态访问了。我们也需要设置一个静态变量来访问数据库。@Autowiredprivatesta......
  • 78、使用Jenkins Docker 部署SpringBoot项目
    1、centOS安装Docker1、更新软件源:yumupdate2、卸载旧版本:yumremovedockerdocker-commondocker-selinuxdocker-engine3、安装软件包:yuminstall-yyum-utils......
  • 关于成本标签管理-基于-Resource Groups & Tag Editor-统计指定Project-所有资源
    背景:因我们所有AWS都是使用Project标签作为成本标签的,今天因一个项目决定彻底退役下线于是决定要完全清理此项目的所有资源,防止继续产生费用~ 首先想到的去通过Project......
  • Resource和Autowired区别
     使用场景:@Resource和@Autowired都是做bean注入时使用@Resourece是JDK的注解,不是spring的注解;由包javax.annotation.Resourece提供,需要导入;但是Spring支持该......
  • NC19782 Tree
    题目链接题目题目描述修修去年种下了一棵树,现在它已经有n个结点了。修修非常擅长数数,他很快就数出了包含每个点的连通点集的数量。澜澜也想知道答案,但他不会数数,于是......
  • AT4783 题解
    题目传送门小学生又双叒叕来写题解啦!这题的关键就是贪心。看到N的范围,瞬间明白可能要排序。所以我们靠着排序来想。我们来思考一下怎样安排顺序。对于两个时间限......
  • AT278 题解
    题目传送门小学生又双叒叕来写题解啦!我的思路是,先统计招牌与材料包中不同字母的数量。然后,枚举二十六个字母。对于每个字母,用招牌字母数除以材料包字母数,再向上取整。......
  • AT1578 题解
    题目传送门小学生又双叒叕来写题解啦!个人认为这题就考你的理解能力,因此,得先把题读懂。寿司就是01或10字符的组合,减少拆开寿司的次数,本质上就是保留完整的寿司。因......
  • ES678新特性
    ECMAScript介绍ECMA:欧洲计算机制造商协会(EuropeanComputerManufacturersAssociation)。ECMAScript:由ECMA国标制定的脚本程序设计语言ES6新特性let关键字:变量声明......