@Autowired和@Resource的区别详解

目录


一、问题背景

在Spring开发中,依赖注入(Dependency Injection,DI)是最核心的功能之一。而在实际开发中,最常用的两个注解就是:

  • @Autowired
  • @Resource

它们都用于完成依赖注入,但底层机制和使用方式存在明显差异,是面试中的高频考点 ⚠️


二、核心区别总结

2.1 对比表

对比点 @Autowired @Resource
来源 Spring JDK(JSR-250)
默认注入方式 按类型(byType) 按名称(byName)
是否支持 @Qualifier ✅ 支持 ❌ 不支持
是否支持 required属性 ✅ 支持 ❌ 不支持
构造器注入 ✅ 支持 ❌ 不支持
推荐使用 ⭐ 推荐 一般较少使用

三、底层装配机制

3.1 @Autowired注入机制

@Autowired 是Spring提供的注解,其默认装配规则是:

  1. 按类型查找Bean(byType)🔍

  2. 如果找到多个候选Bean:

    • 再根据变量名匹配(byName)
  3. 如果仍无法确定:

    • 抛出异常 ❌

示例

1
2
@Autowired
private UserService userService;

多实现类情况

1
2
3
@Autowired
@Qualifier("userServiceImpl1")
private UserService userService;

特点

  • 支持 required=false(可选注入)👇
1
@Autowired(required = false)
  • 支持三种注入方式:

    • 属性注入
    • setter注入
    • 构造器注入(⭐推荐)

3.2 @Resource注入机制

@Resource 来自 JSR-250 规范,其默认装配规则是:

  1. 按名称查找Bean(byName)🎯

  2. 如果找不到:

    • 再按类型查找(byType)
  3. 如果仍找不到:

    • 抛出异常 ❌

示例

1
2
@Resource
private UserService userService;

等价于:

1
@Resource(name = "userService")

四、核心差异分析(面试重点🔥)

4.1 注入方式不同

  • @Autowired:按类型注入(byType)🔍
  • @Resource:按名称注入(byName)🎯

👉 这是两者最本质的区别

4.2 多实现类处理方式

@Autowired

需要配合 @Qualifier 使用:

1
2
3
@Autowired
@Qualifier("userServiceImpl1")
private UserService userService;

@Resource

直接指定名称:

1
2
@Resource(name = "userServiceImpl1")
private UserService userService;

4.3 功能支持差异

功能 @Autowired @Resource
required控制 ✅ 支持 ❌ 不支持
构造器注入 ✅ 支持 ❌ 不支持
Spring扩展能力 💪 强 ⚠️ 较弱

4.4 标准与实现

  • @Autowired:Spring框架提供 👉 功能更强
  • @Resource:Java标准注解 👉 通用性更好但能力有限

五、常见问题与坑

5.1 @Autowired多实现类报错

1
2
@Autowired
private UserService userService;

如果存在多个实现类,会抛出:

1
NoUniqueBeanDefinitionException

解决方式 👇

1
2
@Autowired
@Qualifier("userServiceImpl1")

5.2 @Resource名称不匹配

1
2
@Resource
private UserService userService;

如果容器中没有名为 userService 的Bean:

  • ❌ 直接注入失败并报错

👉 本质原因:它优先按名称查找

5.3 @Resource不支持构造器注入

1
2
public UserController(@Resource UserService userService) {
}

这种写法是错误的 ❌

👉 @Resource 不能用于构造器参数


六、最佳实践(重要🔥)

6.1 优先使用@Autowired

原因:

  • 💪 Spring生态支持更好
  • ⚙️ 功能更强
  • 🔧 可扩展性更高

6.2 推荐使用构造器注入

1
2
3
4
5
6
7
8
public class UserController {

private final UserService userService;

public UserController(UserService userService) {
this.userService = userService;
}
}

说明:

  • Spring 4.3+ 单构造器可省略 @Autowired
  • ✅ 更利于测试(方便Mock)
  • ✅ 避免循环依赖问题

6.3 特定场景使用@Resource

适用于:

  • 明确需要按名称注入 🎯
  • 兼容老项目(非Spring标准体系)

七、面试总结

可以这样回答面试官:

@Autowired是Spring提供的依赖注入注解,默认按类型注入,支持@Qualifier和构造器注入,功能更强;
@Resource是JDK提供的注解,默认按名称注入,优先按名称匹配,功能相对较弱;
实际开发中通常推荐使用@Autowired。