一文搞懂Spring中@Autowired和@Resource的区别

目录
  • 1.来源不同
  • 2.依赖查找顺序不同
    • 2.1 @Autowired 查找顺序
    • 2.2 @Resource 查找顺序
    • 2.3 查找顺序小结
  • 3.支持的参数不同
  • 4.依赖注入的支持不同
  • 5.编译器提示不同
  • 总结

@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 注解则不会提示错误。

以上就是一文搞懂Spring中@Autowired和@Resource的区别的详细内容,更多关于Spring @Autowired @Resource区别的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理

    一.spring依赖注入使用方式 @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byType的,如果存在多个同一类型的bean,则使用@Qualifier来指定注入哪个beanName的bean. 与JDK的@Resource的区别:@Resource是基于bean的名字,即beanName,来从spring的IOC容器查找bean注入的,而@Autowried是基于类型byType

  • Spring@Autowired与@Resource的区别有哪些

    @Autowired与@Resource都是我们日常开发中常用的两个注解,那么它们之间究竟有何区别呢? 开始讲解之前我们首先要明白一点,这个两个注解都是用来完成组件的装配的,即利用依赖注入(DI),完成对ioc容器当中各个组件之间依赖的装配赋值. @Autowired注解 来源:@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired. 说明:@Autowired采取的默认策略为按照类型注

  • Spring框架中 @Autowired 和 @Resource 注解的区别

    Spring框架中 @Autowired 和 @Resource 注解的区别 在 spring 框架中,除了使用其特有的注解外,使用基于 JSR-250 的注解,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释. 首先,咱们简单了解 @PostConstruct 和 @PreDestroy 注释: 为了定义一个 bean 的安装和卸载,我们可以使用 init-method 和 destroy-method 参数简单的声明一下 ,其中 init-meth

  • Spring中@Autowired与@Resource的区别详析

    目录 一.定义 二.区别 总结 一.定义 @Autowired 对类成员变量.方法及构造函数进行标注,完成自动装配的工作. @Resource 在语义上被定义为通过其唯一的名称来标识特定的目标组件,其中声明的类型与匹配过程无关. 如果没有明确指定名称,则默认名称是从字段名称或设置方法(get.set方法)派生的. 如果用在字段上,则采用字段名称; 如果用在在setter方法,它采用其属性名称(例如setProperty()方法,取property做为属性名称). 二.区别 在Spring框架中,

  • Spring注解@Resource和@Autowired区别对比详解

    前言 @Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入. 1.共同点 两者都可以写在字段和setter方法上.两者如果都写在字段上,那么就不需要再写setter方法. 2.不同点 (1)@Autowired @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory

  • 一文搞懂Spring中@Autowired和@Resource的区别

    目录 1.来源不同 2.依赖查找顺序不同 2.1 @Autowired 查找顺序 2.2 @Resource 查找顺序 2.3 查找顺序小结 3.支持的参数不同 4.依赖注入的支持不同 5.编译器提示不同 总结 @Autowired 和 @Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解.它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同,并且这也是常见的面试题之一,所以我们今天就来盘它. @Autowired 和 @Resource 的区

  • 一文搞懂Spring中的Bean作用域

    目录 概述 Singleton prototype request session application 概述 scope用来声明容器中的对象所应该处的限定场景或者说该对象的存活时间,即容器在对象进入其 相应的scope之前,生成并装配这些对象,在该对象不再处于这些scope的限定之后,容器通常会销毁这些对象. Spring容器bean的作用域类型: singleton:Spring IoC 容器的单个对象实例作用域都默认为singleton prototype:针对声明为拥有prototyp

  • 一文搞懂Spring中的注解与反射

    目录 前言 一.内置(常用)注解 1.1@Overrode 1.2@RequestMapping 1.3@RequestBody 1.4@GetMapping 1.5@PathVariable 1.6@RequestParam 1.7@ComponentScan 1.8@Component 1.9@Service 1.10@Repository 二.元注解 @Target @Retention @Documented @Inherited 三.自定义注解 四.反射机制概述 4.1动态语言与静态语

  • 一文搞懂Spring中Bean的生命周期

    目录 一.使用配置生命周期的方法 二.生命周期控制——接口控制(了解) 小结 生命周期:从创建到消亡的完整过程 bean声明周期:bean从创建到销毁的整体过程 bean声明周期控制:在bean创建后到销毁前做一些事情 一.使用配置生命周期的方法 在BookDaoImpl中实现类中创建相应的方法: //表示bean初始化对应的操作 public void init(){ System.out.println("init..."); } //表示bean销毁前对应的操作 public v

  • 一文搞懂Vue中computed和watch的区别

    目录 一.computed介绍 1.1.get 和 set 用法 1.2.计算属性缓存 二.watch介绍 三.两者区别 3.1.对于 computed 3.2.对于 watch 四.应用场景 一.computed介绍 computed 用来监控自己定义的变量,该变量在 data 内没有声明,直接在 computed 里面定义,页面上可直接使用. //基础使用 {{msg}} <input v-model="name" /> //计算属性 computed:{ msg:fu

  • 一文搞懂Spring中的JavaConfig

    目录 配置类 注册组件 扫描包配置 事务注解驱动 单元测试加载配置类 properties配置文件加载(了解) aspectj注解开关 传统spring一般都是基于xml配置的,不过后来新增了许多JavaConfig的注解.特别是springboot,基本都是清一色的java config,不了解一下,还真是不适应.这里给大家普及下Spring中的JavaConfig知识. 什么是JavaConfig.通过注解和配置类完成Spring的相关配置 Spring配置都做了什么? 注册组件.其他配置(

  • 一文搞懂Spring Bean中的作用域和生命周期

    目录 一.Spring Bean 作用域 singleton(单例) prototype(原型) 小结 二.Spring Bean生命周期 如何关闭容器 生命周期回调 通过接口设置生命周期 通过xml设置生命周期 一.Spring Bean 作用域 常规的 Spring IoC 容器中Bean的作用域有两种:singleton(单例)和prototype(非单例) 注:基于Web的容器还有其他种作用域,在这就不赘述了. singleton(单例) singleton是Spring默认的作用域.当

  • 一文搞懂Spring循环依赖的原理

    目录 简介 循环依赖实例 测试 简介 说明 本文用实例来介绍@Autowired解决循环依赖的原理.@Autowired是通过三级缓存来解决循环依赖的. 除了@Autoired,还有其他方案来解决循环依赖的,见:Spring循环依赖的解决方案详解 概述 @Autowired进行属性注入可以解决循环依赖.原理是:Spring控制了bean的生命周期,先实例化bean,后注入bean的属性.Spring中记录了正在创建中的bean(已经实例化但还没初始化完毕的bean),所以可以在注入属性时,从记录

  • 一文搞懂SpringMVC中@InitBinder注解的使用

    目录 简介 应用示例 原理解读 环境:Springboot2.4.12 简介 ​@Controller或@ControllerAdvice类可以有@InitBinder方法来初始化WebDataBinder的实例,这些方法可以: 将请求参数(即表单或查询数据)绑定到模型对象. 将基于字符串的请求值(如请求参数.路径变量.头.cookie等)转换为控制器方法参数的目标类型. 渲染HTML表单时,将模型对象的值格式化为字符串值. @InitBinder方法可以注册控制器特定的java.bean.Pr

随机推荐