@Autowired 和 @Resource 都是用于依赖注入的注解,但它们来自不同的规范,在注入行为上也有明显区别。
| 对比项 | @Autowired | @Resource |
|---|---|---|
| 所属规范 | Spring 原生注解 | JSR-250 标准注解(Java 原生) |
| 默认注入方式 | byType(根据类型匹配) | byName(根据名称匹配) |
| 匹配策略 | 1. 按类型查找 2. 若有多个相同类型,按名称(字段名/参数名)二次匹配 3. 可使用 @Qualifier 指定名称 |
1. 默认按名称匹配 2. 若未找到名称匹配,回退为按类型匹配 |
| 属性设置 | 必需属性:required=true(找不到时抛异常) |
不支持 required 属性(找不到时返回 null 或抛异常取决于配置) |
| 适用位置 | 构造器、方法、参数、字段 | 仅字段、setter 方法 |
| 对 JDK/框架依赖 | 强依赖 Spring | 弱依赖(属于 Java 通用注解) |
核心区别详解
1. 注入规则不同
-
@Autowired :优先
byType。例如:
@Autowired private UserService userService;Spring 先找类型为
UserService的 Bean。如果找到唯一匹配,直接注入;如果找到多个,再用变量名userService作为 Bean 名称去匹配;如果还匹配不到,就用@Qualifier显式指定。 -
@Resource :优先
byName。它有两个重要属性:
name和type。- 指定
name:按名称查找 - 指定
type:按类型查找 - 都未指定:先按字段名找;找不到再按类型找
示例:@Resource(name="myService")强制按名称查找。
- 指定
2. 是否必须依赖
@Autowired的required默认为true,找不到会报错。可设为false允许为 null。@Resource没有required属性。如果按规则找不到 Bean,JSR-250 规范要求抛出异常(Spring 会抛出NoSuchBeanDefinitionException)。
3. 适用范围
@Autowired可以用在构造器上实现构造器注入(推荐用于必须的依赖)。@Resource不能用于构造器或方法参数。
选择建议
- 代码依赖 Spring :优先
@Autowired(配合@Qualifier),灵活且功能强。 - 希望解耦 Spring 规范 :使用
@Resource,遵循 Java 标准,便于将来迁移到其他 CDI 容器。 - 构造器注入 :只能用
@Autowired(或直接用@Inject来自 JSR-330)。
实际项目中两者混用也很常见,只要理解其行为差异即可避免注入冲突。