@Resource和 @Autowired都是用于依赖注入的注解,但它们有以下主要区别:
1. 来源不同
@Autowired:Spring 框架提供的注解@Resource:JavaEE 规范(JSR-250)中的注解,Spring 对其提供支持
2. 注入方式不同
@Autowired
// 默认按类型(byType)注入
@Autowired
private UserService userService;
// 如果有多个同类型Bean,需配合@Qualifier按名称注入
@Autowired
@Qualifier("userServiceImplA")
private UserService userService;
@Resource
// 1. 指定name时,按名称(byName)注入
@Resource(name = "userServiceImplA")
private UserService userService;
// 2. 不指定name时,先按字段/属性名匹配
// 如果找不到,再按类型匹配
@Resource
private UserService userServiceImplA; // 会找名为userServiceImplA的Bean
3. 必需性不同
// @Autowired 可设置required=false,允许注入null
@Autowired(required = false)
private UserService userService; // 允许为null
// @Resource 没有required属性,但可以通过指定name避免歧义
@Resource
private UserService userService; // 默认必须存在
4. 适用范围
// @Autowired 可用于更多地方
@Autowired
private UserService field; // 字段
@Autowired
public void setService(UserService service) { // setter方法
this.service = service;
}
@Autowired
public UserController(UserService service) { // 构造器
this.service = service;
}
// @Resource 不能用于构造器
@Resource
public void setService(UserService service) { // 只能用于字段和setter
this.service = service;
}
5. 与Spring的集成
// @Autowired 是Spring原生支持,功能更丰富
@Autowired
private ApplicationContext context; // 可直接注入Spring容器
// @Resource 需要启用相应支持
// 在配置类上需要添加
@Configuration
@ComponentScan
public class AppConfig {
// 自动支持@Resource
}
6. 常见使用场景对比
场景1:按类型注入
// 推荐使用@Autowired
@Service
public class OrderService {
@Autowired // 清晰表明按类型注入
private PaymentService paymentService;
}
场景2:按名称注入
// 推荐使用@Resource
@Service
public class UserService {
@Resource(name = "jdbcUserRepository") // 明确指定Bean名称
private UserRepository repository;
}
场景3:有多个实现时
// 方案1:使用@Autowired + @Qualifier
@Component
public class NotificationService {
@Autowired
@Qualifier("smsNotifier")
private Notifier notifier;
}
// 方案2:使用@Resource
@Component
public class NotificationService {
@Resource(name = "smsNotifier")
private Notifier notifier;
}
7. 最佳实践建议
| 场景 | 推荐注解 | 原因 |
|---|---|---|
| Spring项目,按类型注入 | @Autowired | Spring原生,更符合Spring风格 |
| 需要按名称精确匹配 | @Resource | 语义更明确 |
| 多实现类,需指定具体Bean | @Resource或 @Autowired+@Qualifier | 根据团队习惯选择 |
| 非Spring项目(JavaEE) | @Resource | 标准JavaEE注解 |
| 构造器注入 | @Autowired | @Resource不支持构造器 |
8. 性能考虑
两者在性能上差异不大,但:
@Autowired的解析由Spring的AutowiredAnnotationBeanPostProcessor处理@Resource的解析由CommonAnnotationBeanPostProcessor处理- 在大型应用中,统一使用一种注解有助于减少处理器数量
总结
// 简单总结:
// 1. 如果是纯Spring项目,习惯用@Autowired
// 2. 如果需要精确按名称注入,用@Resource更直观
// 3. 团队统一风格最重要
实际开发中,大部分团队会选择其中一种作为主要注入方式,保持代码风格统一。在Spring Boot项目中,@Autowired更常见。