@Autowired 和 @Resource 注解有啥区别?你这项目怎么还混着用呢?

面试考察点

  1. 基础掌握度:面试官不仅仅是想知道这两个注解 "不一样",更是想看你能不能从来源、匹配策略、使用方式等多个维度做系统对比,而不是只背出 "一个是 Spring 的,一个是 JDK 的"。
  2. 底层原理 :是否理解 @Autowired 的 "先类型后名称" 和 @Resource 的 "先名称后类型" 的匹配机制,以及当存在多个候选 Bean 时各自怎么处理冲突。
  3. 实践选型:考察你在项目中如何选择这两个注解,是否了解 Spring 官方的推荐做法,以及新版 Spring Boot 中的变化。

核心答案

先上对比表格,一目了然:

维度 @Autowired @Resource
来源 Spring 框架(org.springframework.beans.factory.annotation JSR-250 规范(jakarta.annotation / javax.annotation
匹配策略 先按类型(byType) ,有多个再按名称 先按名称(byName) ,没找到再按类型
指定名称 配合 @Qualifier("beanName") 直接 @Resource(name = "beanName")
required 属性 支持 required = false,注入失败不报错 不支持,注入失败直接抛异常
适用位置 构造器、方法、参数、字段 方法、字段
官方推荐 Spring 官方推荐 ---

核心区别就一句话:@Autowired 先类型后名称,@Resource 先名称后类型

深度解析

一、匹配机制的差异

这是面试官最想听的部分。用一张流程图来对比两者的注入策略:

两个流程图分别展示了两种注解的注入策略,关键区别在于优先级不同:

  • @Autowired 的策略 :Spring 先按类型去容器里找,如果只找到一个,直接注入,皆大欢喜。但如果找到多个同类型的 Bean,Spring 会尝试用字段名去匹配 Bean 名称,匹配上了就用。如果还匹配不上,就得靠 @Qualifier 显式指定。另外 @Autowired 支持 required = false,允许注入失败时不报错,这在某些可选依赖的场景很有用。
  • @Resource 的策略 :正好反过来。它先看有没有指定 name,或者直接用字段名当 Bean 名称去容器里找。找到了就注入,找不到才退回按类型查找。但 @Resource 没有 required 属性,找不到就报错,没有商量的余地。

二、当存在多个同类型 Bean 时怎么办

这是实际开发中经常遇到的场景。假设你有两个 UserService 的实现:

less 复制代码
@Service
public class UserServiceImpl implements UserService { }

@Service("vipUserService")
public class VipUserServiceImpl implements UserService { }

@Autowired 解决冲突

less 复制代码
@Component
public class OrderController {

    // 方式一:配合 @Qualifier 指定名称
    @Autowired
    @Qualifier("vipUserService")
    private UserService userService;

    // 方式二:字段名恰好是 Bean 名称(Spring 会自动回退到名称匹配)
    @Autowired
    private UserService vipUserService;
}

@Resource 解决冲突

kotlin 复制代码
@Component
public class OrderController {

    // 直接用 name 属性指定
    @Resource(name = "vipUserService")
    private UserService userService;

    // 或者字段名就是 Bean 名称
    @Resource
    private UserService vipUserService;
}

对比下来,@Resource 指定名称的方式更直观,不需要额外加一个注解。

三、能加在哪里?

这个点很多人答不全。

java 复制代码
// @Autowired 能用在这几个地方:

// 1. 字段注入(最常见,但不推荐)
@Autowired
private UserService userService;

// 2. 构造器注入(Spring 官方推荐 ✅)
@Autowired
public OrderController(UserService userService) {
    this.userService = userService;
}

// 3. Setter 方法注入
@Autowired
public void setUserService(UserService userService) {
    this.userService = userService;
}

// 4. 方法参数(Spring 4.3+,如果只有一个构造器,@Autowired 可省略)

@Resource 只能用在字段和方法上,不能标注在构造器上。这一点面试的时候提一下,能加分。

四、Spring Boot 3.x 的变化

如果你面的是 Spring Boot 3.x / Spring 6.x 的项目,有个变化值得提一嘴:

@Resource 的包路径从 javax.annotation 变成了 jakarta.annotation。因为 Java EE 把命名权交给了 Eclipse 基金会,改名叫 Jakarta EE 了。如果你从 Spring Boot 2.x 升级到 3.x,这个 import 路径得改,不然编译都过不了。

另外,Spring Framework 6.1 / Spring Boot 3.2 之后,核心框架自身的注入不再使用 @Autowired,而是全面转向了构造器注入 + 参数自动检测的模式(不需要任何注解,Spring 自动识别构造器参数类型并注入)。这是一个趋势,面试的时候提一下很加分。

五、生产中到底用哪个?

说实话,两种都行,团队统一就好。但 Spring 官方更推荐用构造器注入 (配合 @Autowired 或不加注解),原因有三:

  • 构造器注入能保证依赖不可变(字段可以是 final 的)
  • 依赖关系一目了然,参数太多说明类该拆了
  • 方便单元测试,直接传参就行,不用反射

面试高频追问

  1. 追问一:@Autowired 注入的是接口还是实现类?

    注入的是接口类型,Spring 容器根据类型找到对应的实现类。面向接口编程,解耦的好处就在这。

  2. 追问二:构造器注入和字段注入哪个好?为什么?

    构造器注入更好。字段注入看起来简洁,但隐藏了依赖关系,而且没法把字段声明为 final。构造器注入让依赖一目了然,也方便做单元测试。

  3. 追问三:@Primary 注解是干什么的?和 @Qualifier 有什么区别?

    @Primary 标注在 Bean 上,告诉 Spring "当有多个候选时,优先用我"。它是全局默认选择。@Qualifier 是注入点级别的精确指定,优先级更高。一个管全局,一个管局部。

常见面试变体

  • "@Autowired@Resource 的注入方式有什么不同?"
  • "当有多个同类型 Bean 时,Spring 怎么决定注入哪一个?"
  • "Spring 官方推荐哪种依赖注入方式?"

记忆口诀

@Autowired :Spring 家的, 先类型后名称 ,配合 @Qualifier 精确定位。

@Resource :JSR 标准的, 先名称后类型name 属性一步到位。

总结

这两个注解的核心区别就是匹配策略的优先级不同。@Autowired 先类型后名称,@Resource 先名称后类型。面试时把这个区别讲清楚,再提一下构造器注入的优势和 Spring 6.x 的新趋势,这道题稳拿。

相关推荐
程序员小假2 小时前
HTTP3 性能更好,为什么内网微服务依然多用 HTTP2?HTTP2 内网优势是什么?
java·后端
wangbing11252 小时前
踩坑:el8应用装在el9上
开发语言·后端·ruby
kyriewen113 小时前
你等的Babel编译,够喝三杯咖啡了——用Rust重写的SWC,只需眨个眼
开发语言·前端·javascript·后端·性能优化·rust·前端框架
IT_陈寒3 小时前
SpringBoot自动配置坑了我,原来要这样绕过去
前端·人工智能·后端
东方小月3 小时前
Claude Code 完整上手指南:MCP、Skills、第三方模型配置一次搞定
前端·人工智能·后端
凤山老林4 小时前
从0到1搭建企业级权限管理系统:Spring Boot + JWT + RBAC实战指南
java·spring boot·后端·权限管理·rbac
ray_liang4 小时前
吐血整理JSON-RPC2.0的原理与应用
后端
蝎子莱莱爱打怪4 小时前
Claude Code 省 Token 小妙招:RTK + Caveman 组合拳
前端·人工智能·后端
Soofjan4 小时前
Redis(3):RDB 与 AOF、BGSAVE 与写时复制
后端