@Resource 和 @Autowired 都是 Java 中用于自动装配 Bean 的注解,尤其在 Spring 框架中被广泛使用,但它们在多个方面存在区别:
1.所属规范:
- @Resource 是 Java 标准 JSR-250 规范中的注解,由 JCP(Java Community Process)制定。这意味着只要遵循 JSR-250 规范的容器,理论上都可以使用 @Resource 注解,具有一定的通用性,不局限于 Spring 框架。
- @Autowired 是 Spring 框架特有的注解,由 Spring 框架提供和维护。如果项目不使用 Spring 框架, @Autowired 注解将无法使用。
2.装配机制:
- @Resource 默认按照名称进行装配。当找不到与名称匹配的 Bean 时,才会尝试按照类型进行装配。例如,在一个类中使用 @Resource 注解标注一个字段: @Resource private UserService userService; ,Spring 会首先查找名称为 userService 的 Bean,如果不存在,再查找类型为 UserService 的 Bean 进行装配。
- @Autowired 是按照类型进行装配的。当容器中存在多个相同类型的 Bean 时, @Autowired 会装配失败,因为它无法确定要注入哪个具体的 Bean。此时需要结合 @Qualifier 注解来指定要注入的 Bean 的名称。比如 @Autowired @Qualifier("userServiceBean") private UserService userService; 就是先按类型 UserService 查找,再根据 userServiceBean 这个名称来确定具体的 Bean。
3.作用位置:
- @Resource 可以作用在字段上,也可以作用在 setter 方法上。例如:
// 作用在字段上
public class OrderService {
@Resource
private OrderRepository orderRepository;
}
// 作用在setter方法上
public class OrderService {
private OrderRepository orderRepository;
@Resource
public void setOrderRepository(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
- @Autowired 不仅可以作用在字段和 setter 方法上,还可以作用在构造函数、普通方法(包含有参数的方法)上。例如:
// 作用在字段上
public class ProductService {
@Autowired
private ProductRepository productRepository;
}
// 作用在setter方法上
public class ProductService {
private ProductRepository productRepository;
@Autowired
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
// 作用在构造函数上
public class ProductService {
private ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
// 作用在普通方法上
public class ProductService {
private ProductRepository productRepository;
@Autowired
public void someMethod(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
4.是否允许为 null:
- @Resource 允许被注入的 Bean 为 null,当找不到匹配的 Bean 时,不会抛出异常,只是注入的属性值为 null。
- @Autowired 默认情况下,如果找不到匹配的 Bean,会抛出 NoSuchBeanDefinitionException 异常。但可以通过设置 @Autowired 的 required 属性为 false 来允许注入为 null,例如: @Autowired(required = false) private UserService userService; 。
综上所述, @Resource 和 @Autowired 在所属规范、装配机制、作用位置和对 null 值的处理上都存在差异,开发者可根据具体需求和场景选择合适的注解来实现 Bean 的自动装配。