@Autowired
和 Resource
都是 Spring 生态中实现依赖注入的核心注解,但两者在设计来源、注入规则和应用场景上存在显著差异。以下是两者的详细对比:
1. 来源与规范支持
-
@Autowired
-
来源:Spring 框架自研注解(org.springframework.beans.factory.annotation)。
-
兼容性:仅适用于 Spring 容器,强耦合于 Spring 生态。
-
-
@Resource
-
来源:Java EE 规范(JSR-250),包路径为javax.annotation.Resource。
-
兼容性:作为 Java 标准注解,支持任何兼容 JSR-250 的框架(如 Jakarta EE),不依赖 Spring。
-
2. 默认注入策略
-
@Autowired
-
默认策略:按类型匹配(byType)。
-
多 Bean 冲突处理:
-
需配合@Qualifier("beanName")指定名称;
-
或用@Primary标记优先注入的 Bean
-
@Autowired @Qualifier("userServiceImpl") private UserService userService; // 显式指定 Bean 名称
-
-
@Resource
-
默认策略:按名称匹配(byName),默认使用字段名作为 Bean 名称。
-
多 Bean 冲突处理:
-
通过name或type属性灵活指定注入方式;
-
未指定时,先按名称匹配,失败后再按类型匹配。
-
@Resource(name = "userService", type = UserServiceImpl.class) private UserService userService; // 同时指定名称和类型
-
3. 参数与灵活性
-
@Autowired
-
参数:仅支持required(默认true),设为false时允许注入失败(字段为null)。
@Autowired(required = false) private OptionalService optionalService; // 允许注入为空
-
-
@Resource
-
参数:支持name、type、authenticationType等 7 个属性,提供更精细的控制。
@Resource(name = "jdbcDataSource", lookup = "java:/comp/env/jdbc/DB") private DataSource dataSource; // 支持 JNDI 资源注入
-
4. 装配顺序对比
注解 | 装配顺序 |
---|---|
@Autowired | 1. 按类型匹配 → 2. 按名称匹配(字段名) → 3. 冲突时需 @Qualifier 或 `@Primary。 |
@Resource | 1. 按 name 属性匹配 → 2. 未指定 name 时按字段名匹配 → 3. 按 type 匹配 → 4. 按类型回退。 |
5. 应用范围
-
@Autowired
-
支持位置:字段、构造方法、普通方法、参数、注解。
@Autowired public UserController(UserService service) { // 构造器注入 this.userService = service; }
-
-
@Resource
-
支持位置:字段、Setter 方法、类(较少用)。
@Resource public void setUserService(UserService service) { // Setter 注入 this.userService = service; }
-
总结:如何选择?
场景 | 推荐注解 | 理由 |
---|---|---|
纯 Spring 项目,需类型优先注入 | @Autowired | 简洁,天然支持 Spring 的高级特性(如 @Qualifier )。 |
需跨框架兼容(如 Jakarta EE) | @Resource | 符合 Java 标准,避免框架绑定。 |
需按名称精确注入 | @Resource | 直接通过 name 属性指定,无需额外注解。 |
注入可选依赖(允许 null) | @Autowired(false) | 通过 required=false 快速实现。 |
最佳实践:
在 Spring Boot 项目中,两者均可使用,但团队需统一规范;
若需明确依赖名称(如多数据源切换),优先用@Resource;
构造器注入推荐@Autowired(更符合 Spring 官方建议)。