★ @Autowired 与 @Resource 区别
结论先行:二者都是依赖注入注解,核心差异一句话:@Autowired 是 Spring 的,默认按类型(byType)装配,类型不唯一时再按字段名/参数名匹配,可用 @Qualifier/@Primary 定点;@Resource 是 JSR-250(jakarta.annotation)标准,默认按名称(byName)装配,找不到名再退化为按类型,可用 name/type 属性显式指定。Spring 项目首选 @Autowired 构造器注入;确实要"按名字"或强调 Java 标准兼容性时用 @Resource。
一、对比表
| 对比项 | @Autowired | @Resource |
|---|---|---|
| 所属 | Spring(org.springframework.beans.factory.annotation) | JSR-250 / jakarta.annotation |
| 默认策略 | byType,多候选再按字段名/参数名 | byName(字段名/setter 属性名),再退化为 byType |
| 指定名称 | @Qualifier("xxx") 配合使用 | name = "xxx"(或 type 属性) |
| 同类型多 Bean | @Primary 优先,@Qualifier 精确定位 | name 精确定位 |
| required(可为空) | 支持 required = false | 不支持,必须解析成功 |
| 构造器注入 | 支持(推荐) | 不支持 |
| 适用范围 | Spring 容器 | Spring 容器(Spring 提供实现),也兼容 Java EE |
二、代码对比
@Service
public class OrderService {
@Resource(name = "alipayPayService") // ① 按名称精确装配
private PayService alipay;
@Autowired // ② 按类型;有多个 PayService 实现时会失败
@Qualifier("wechatPayService") // ③ 类型 + 限定名 → 定点
private PayService wechat;
private final PayService pay; // ④ 构造器注入(最推荐,单实现时最简洁)
public OrderService(PayService pay) { this.pay = pay; }
}
常见追问 / 记忆点
- 追问 1:同一个接口有多个实现类时怎么办?答:@Primary 标记默认实现;@Qualifier("beanName") 指定;@Resource(name = "...") 指定;或注入 List<PayService> 拿全部再分派。
- 追问 2:@Autowired 多候选时真的会按字段名吗?答:会——findAutowireCandidates 之后若候选多于一个,再按字段名/参数名与 beanName 匹配,匹配到唯一才成功,否则报 NoUniqueBeanDefinitionException。
- 追问 3:两者能混用吗?答:能,但风格要统一,团队规范二选一。
- 记忆点:"Autowired 先类型、Resource 先名字";A 是 Spring 私有、R 是标准注解;构造器注入用 @Autowired。