在Spring框架中,@Autowired
、@Qualifier
和@Resource
都是用于依赖注入的注解,但它们在使用方式和功能上有一些重要区别。
一、注解介绍
1. @Autowired
来源:Spring框架原生注解
包:org.springframework.beans.factory.annotation
特点:
-
默认按类型(byType)自动装配
-
可以与
@Qualifier
配合使用实现按名称装配 -
支持required属性(
@Autowired(required=false)
) -
可以用于构造器、字段、方法和参数
示例:
@Service
public class UserService {
@Autowired // 按类型自动注入
private UserRepository userRepository;
@Autowired // 构造器注入
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
2. @Qualifier
来源:Spring框架原生注解
包:org.springframework.beans.factory.annotation
特点:
-
用于解决当有多个相同类型的Bean时的歧义问题
-
必须与
@Autowired
配合使用 -
通过指定Bean的名称进行精确装配
示例:
@Service
public class PaymentService {
@Autowired
@Qualifier("creditCardProcessor") // 指定注入特定名称的Bean
private PaymentProcessor processor;
}
@Component("creditCardProcessor")
public class CreditCardProcessor implements PaymentProcessor {}
@Component("paypalProcessor")
public class PaypalProcessor implements PaymentProcessor {}
3. @Resource
来源:Java标准注解(JSR-250)
包:javax.annotation
特点:
-
默认按名称(byName)自动装配
-
如果未指定name属性,则退化为按类型(byType)装配
-
是Java标准注解,不依赖Spring框架
-
不能用于构造器注入
示例:
@Service
public class OrderService {
@Resource(name = "orderRepositoryImpl") // 按名称注入
private OrderRepository repository;
@Resource // 未指定name,先按名称再按类型
private UserService userService;
}
二、三者的主要区别
特性 | @Autowired | @Qualifier | @Resource |
---|---|---|---|
来源 | Spring框架 | Spring框架 | Java标准(JSR-250) |
默认装配方式 | 按类型(byType) | 必须配合@Autowired使用 | 按名称(byName) |
支持构造器注入 | 支持 | 不支持 | 不支持 |
required属性 | 有 | 无 | 无 |
单独使用 | 可以 | 不可以 | 可以 |
指定Bean名称 | 需配合@Qualifier | 用于指定名称 | 通过name属性指定 |
使用场景 | Spring项目中的首选方式 | 解决多Bean歧义问题 | 需要与JavaEE兼容的项目 |
三、使用建议
-
推荐使用
@Autowired
:-
纯Spring项目中的首选。
-
更符合Spring的设计哲学。
-
支持更灵活的注入方式(构造器、字段等)。
-
-
需要解决歧义时:
@Autowired @Qualifier("specificBean") private MyInterface bean;
-
需要与JavaEE兼容时使用
@Resource
:-
当项目可能需要脱离Spring环境时。
-
需要与其他JavaEE容器兼容时。
-
-
构造器注入推荐(Spring 4.3+):
@Service public class MyService { private final MyRepository repository; // Spring 4.3+可以省略@Autowired public MyService(MyRepository repository) { this.repository = repository; } }
四、实际应用实例
// 定义多个同类型Bean
@Component("smsSender")
public class SmsNotificationSender implements NotificationSender {}
@Component("emailSender")
public class EmailNotificationSender implements NotificationSender {}
// 使用不同的注入方式
@Service
public class NotificationService {
// 方式1: @Autowired + @Qualifier
@Autowired
@Qualifier("smsSender")
private NotificationSender primarySender;
// 方式2: @Resource按名称
@Resource(name = "emailSender")
private NotificationSender secondarySender;
// 方式3: 构造器注入(推荐)
private final NotificationSender backupSender;
public NotificationService(@Qualifier("smsSender") NotificationSender backupSender) {
this.backupSender = backupSender;
}
}