当前位置: 首页 > news >正文

@Autowired和@Resource的区别是?

前情回顾

  • 正确使用@Autowired

    • @Autowired 注解在构造器上的使用规则(字段注入也挺好的)
  • 正确使用@Resource

来源不同

  • @Autowired的“爹”是Spring

  • @Resource的“爹”是Java(JSR-250)

    • 这是一个规范,Spring对这个注解进行了支持。
    • 如果换了其他的框架,大概率用不了@Autowired(除非兼容了),大概率能用@Resource(毕竟是Java规范,框架应该会支持的)

当然了,这一点了解下就行了。毕竟实际开发中用的框架是Spring,这两个注解都能用。

查找bean的方式不同(重点)

简单

  • @Autowired:根据类型去查找bean,如果找到了多个,那么再根据名称去选择注入哪一个。

    • 找到了多个,名称是helloService,不匹配,因此不知道注入哪一个。

      image

    • 将名称换成helloServiceImpl1,就能唯一匹配bean了。而且IDEA会提示实际注入了哪个bean(见下图的小红框。)

      image

      虽然cursor很猛,但在Java领域,IDEA还是王者啊。

    • 不过,一般会用另一个注解来指定名称:

      /**
       * @author: Forrest
       * @since: 2025/3/15
       */
      @RestController
      public class HelloController {
          @Qualifier("helloServiceImpl2")
          @Autowired
          private HelloService helloService;
      
          @GetMapping("/hello")
          public String hello() {
              return helloService.sayHello();
          }
      }
      
      • 这个还是有使用场景的,例如要重构了,从helloServiceImpl1切换为helloServiceImpl2。当然了,如果很多地方都用到了helloService,这样修改是不方便的,应该在helloService的实现中完成路由,即helloServiceImpl1内部切换为helloServiceImpl2。(这样想,Service层的约定:接口 + 实现,非常鸡肋…)

  • @Resource:根据名称去查找bean,未找到,再根据类型去查找,如果找到多个,会抛异常。

    image

    image

    左侧查看实际注入时,会发现有两个bean。

    • 指定名称:

      image

    • 用@Qualifier更合适

      /**
       * @author: Forrest
       * @since: 2025/3/15
       */
      @RestController
      public class HelloController {
          @Qualifier("helloServiceImpl2")
          @Resource
          private HelloService helloService;
      
          @GetMapping("/hello")
          public String hello() {
              return helloService.sayHello();
          }
      }
      

进阶

@Autowired、@Resource都支持@Primary(Spring Boot 3.3.7)
  • 上文提到:@Autowired先根据类型去查找bean,如果找到了多个,选哪一个呢?

    • 如果多个bean中,有的bean被打上了@Primary,那么选这个bean。​

      image​​

      image

    • 如果多个bean都被打上了@Primary呢?那继续根据名称来筛选。

  • 对于@Resource,优先按照名称去匹配,如果存在多个,那么匹配被打上@Primary的bean。

要彻底搞明白,还得去看这一块的源码(埋坑)

使用范围不同(挺重要)

特性@Autowired@Resource
注解位置可以注解在字段、构造方法、Setter方法及方法参数上可以注解在字段、Setter方法上
集合类型注入支持,可以用于注入集合类型(如List<XXX>​),自动注入所有符合类型的Bean也支持
数组类型注入支持,可以用于注入数组类型,自动注入所有符合类型的Bean也支持
构造方法注入支持,可以用于构造方法参数的注入不支持构造方法注入

注解的参数不同

特性@Autowired@Resource
支持的参数只支持required​一个参数支持name​、type​等7个参数
依赖存在性默认依赖的Bean必须存在,可以通过required=false​设置为非必须默认依赖的Bean必须存在,不存在会抛出异常
  • @Autowired(required = false) 不是说就不注入依赖了,而是一旦注入失败了, 那就不注入了。也就是不要因为弱依赖而影响了主流程。

  • 对于@Resource,用的最多的是name​、type​。

    • @Resource默认是按名称去查找bean的,因此,最好用name明确这个名称。

      @Resource(type = HelloServiceImpl1.class)
      private HelloService helloService;
      

相关文章:

  • Kubernetes 单节点集群搭建
  • 项目日记 -云备份 -项目认识与环境搭建
  • Android多线程通信机制
  • PyTorch PINN实战:用深度学习求解微分方程
  • 使用 Doris 和 Paimon
  • Vue.js 项目部署全解析:从开发到上线的关键旅程题
  • 【NLP】10. 机器学习模型性能评估指标(含多类别情况), ROC,PRC
  • Day 2
  • DC-6靶机详解
  • pfsense部署(特详细,小白零基础)
  • 钉钉(excel)能让表格中不是‘北京’的字符串自动加亮显示(方便查看)以及隔行填充严颜色是斑马色(方便查看)嘛
  • leetcode hot100普通动态规划/基础DP
  • C++之list类(超详细)
  • 审批工作流系统xFlow
  • 变量与输入输出
  • 【推荐系统全面整理】
  • Django项目之订单管理part3
  • Flink 1.17.2 版本用 java 读取 starrocks
  • Docker部署前端项目——Linux系统
  • 接口测试的原则、用例与流程
  • 广西桂林、百色、河池等地表态:全力配合中央对蓝天立的审查调查
  • 专利申请全球领先!去年我国卫星导航与位置服务产值超5700亿
  • 知名中医讲师邵学军逝世,终年51岁
  • 孟夏韵评《无序的学科》丨误读与重构的文化漂流
  • 当智慧农场遇见绿色工厂:百事如何用科技留住春天的味道?
  • 上海国际碳中和博览会下月举办,首次打造民营经济专区