用最通俗的可视化例子,讲清 @Autowired 和 @Resource

6 阅读4分钟

不用死记硬背,一看就懂! 核心结论:

  • @Autowired:Spring 框架专属注解,默认按类型(byType)匹配,找不到对应类型直接报错;若想按名字匹配,必须搭配 @Qualifier 注解使用。
  • @Resource:Java 官方标准注解(遵循JSR-250规范),默认按名字(byName)匹配,名字匹配失败后,会自动降级按类型匹配,无需额外注解。

一、核心场景:给「水杯」找「水」

为了更直观理解,我们模拟一个真实开发场景:假设你有一个水杯类(Cup) ,需要注入水(Water) ,但此时系统中存在两个水的实现类,具体代码如下:

// 水的接口(定义水的统一规范)
public interface Water {}

// 实现类1:热水(Bean名称为hotWater)
@Component("hotWater")
public class HotWater implements Water {}

// 实现类2:冷水(Bean名称为coldWater)
@Component("coldWater")
public class ColdWater implements Water {}

现在要给Cup类注入Water实例,@Autowired和@Resource的查找逻辑完全不同,我们一步步拆解👇


二、@Autowired 可视化图解(先看类型,再看名字)

查找逻辑:类型优先 → 同名辅助

用生活场景类比:就像你跟服务员说:「给我一杯【水】,不管冷热,只要是水就行」,服务员会先找所有“水”类的饮品,再判断怎么给你。

  1. Spring容器先查找所有实现了 Water 接口的Bean(即所有“水”);
  2. 最终找到2个匹配的Bean:hotWater(热水)、coldWater(冷水);
  3. Spring会直接报错:NoUniqueBeanDefinitionException(找到两个符合类型的Bean,无法确定注入哪一个)。

代码示例(无@Qualifier,直接报错)

@Component
public class Cup {
    // 报错:NoUniqueBeanDefinitionException(找到2个Water类型Bean,无法选择)
    @Autowired
    private Water water;
}

想指定具体注入哪个?必须加 @Qualifier

如果想明确注入热水(hotWater),需要在@Autowired后搭配@Qualifier注解,指定Bean的名字,精准匹配:

@Component
public class Cup {
    // 先按类型找Water,再按@Qualifier指定的名字hotWater精准匹配
    @Autowired
    @Qualifier("hotWater")
    private Water water;
}

可视化总结

@Autowired 查找流程:
【找类型】→ 只找到1个 → 直接注入
【找类型】→ 找到多个 → 报错
【找类型】+ @Qualifier → 精准匹配名字,成功注入

三、@Resource 可视化图解(先看名字,再看类型)

查找逻辑:名字优先 → 类型兜底

还是用生活场景类比:就像你跟服务员说:「给我一杯【名字叫hotWater的水】」,服务员会先精准找这个名字的饮品,找不到再找同类。

  1. Spring容器先查找名字完全匹配的Bean(优先匹配@Resource的name属性);
  2. 找到名字为 hotWater 的Bean,直接注入,无需额外操作,完美匹配!

代码示例(最简单,不用额外注解)

@Component
public class Cup {
    // 直接按name属性匹配hotWater,一步到位,无需额外注解
    @Resource(name = "hotWater")
    private Water water;
}

// 简写技巧:当变量名与Bean名一致时,连name属性都不用写
@Resource
private Water hotWater; // 自动匹配名字为hotWater的Bean

特殊情况:名字找不到,会自动降级按类型找

如果指定的名字找不到,@Resource不会直接报错,会自动降级,按类型查找匹配的Bean:

@Component
public class Cup {
    // 第一步:找名字=abc的Bean → 找不到
    // 第二步:自动降级,找Water类型的Bean → 找到后注入
    @Resource(name = "abc")
    private Water water;
}

可视化总结

@Resource 查找流程:
【找名字】→ 找到 → 直接注入
【找名字】→ 找不到 → 自动降级,按类型匹配
【找名字】+ 按类型 → 都找不到 → 报错

四、终极对比表(一眼看懂核心差异)

特性@Autowired@Resource
归属Spring 框架专属Java 官方标准(跨框架通用)
默认匹配规则按类型(byType)按名字(byName)
多实现类时必须加 @Qualifier 指定名字,否则报错直接用 name 属性 / 变量名匹配,无需额外注解
匹配失败处理找不到对应类型 → 直接报错找不到对应名字 → 自动降级按类型匹配
使用场景纯Spring项目,无需精准指定Bean名字需精准指定Bean、跨框架开发,追求稳健性

五、最简单的使用口诀(记牢不踩坑)

  1. 只有一个实现类:两个注解随便用,效果完全一致,怎么方便怎么来;
  2. 多个实现类,想精准指定:优先用 @Resource,无需额外注解,简洁高效;
  3. 纯Spring项目,需配合 @Qualifier 灵活匹配:用 @Autowired 更贴合Spring生态。

总结

  1. @Autowired = 先看类型,多实现类必报错,需搭配@Qualifier“指名道姓”;
  2. @Resource = 先看名字,精准匹配更灵活,名字找不到自动降级按类型匹配;
  3. 日常开发:优先用 @Resource,指定Bean名字更直观,能有效减少报错,提升开发效率。