在Spring Boot中,@Autowired
和@Resource
注解都用于自动注入依赖,但它们在底层工作方式和使用的场合上存在一些差异。理解这些差异有助于更有效地使用Spring框架。
@Autowired
注解
- 来源:
@Autowired
是Spring框架的注解。 - 注入方式:默认按照类型进行依赖注入。如果找到多个相同类型的bean,则会根据属性名称作为bean的id进行匹配。如果设置
required
属性为false
,当Spring找不到对应的bean时,它将不会抛出异常,而是留下一个未设置的属性。 - 使用场景:通常用于注入应用程序上下文中的bean,支持构造器注入、属性注入和方法注入。
@Resource
注解
- 来源:
@Resource
注解来自Javax注解,是JSR-250规范的一部分。 - 注入方式:默认按名称进行依赖注入。如果没有指定一个名字,它会默认采用被注解的元素的名称。如果按名称注入失败,则会回退到按类型注入。
@Resource
没有required
属性。 - 使用场景:适用于需要按名称进行依赖注入的场景,比如当有多个类型相同的bean需要注入时,通过指定名称来选择具体的bean。
底层注入原理
- 启动时扫描:在Spring容器启动时,会扫描应用中所有的类,查找带有
@Autowired
和@Resource
等注解的字段或方法。 - 依赖解析:
- 对于
@Autowired
:Spring首先按类型进行匹配,如果有多个同类型的bean,则根据属性名(或指定的@Qualifier
)来选择。 - 对于
@Resource
:首先按指定的名称(如果有)进行匹配,失败后再按类型进行匹配。
- 代理和注入:找到匹配的bean后,Spring通过反射等机制将依赖对象注入到目标对象的字段或方法中。
对比优劣
- 类型安全:
@Autowired
提供了更好的类型安全性,因为它默认按类型注入,而且可以结合@Qualifier
注解使用来进一步消除歧义。 - 灵活性:
@Resource
提供了按名称注入的能力,这在某些情况下更为灵活,特别是当存在多个类型相同的bean,而你需要注入其中一个特定的bean时。 - 标准:
@Resource
是基于标准的注解,而@Autowired
是Spring特有的。在某些情况下,如果你想让你的应用尽可能标准化或减少对Spring的依赖,使用@Resource
可能更合适。
总的来说,@Autowired
和@Resource
都是强大的依赖注入功能,适用于不同的场景。选择哪一个主要取决于你的具体需求,比如是否需要按类型安全地注入,或是偏好按名称来选择具体的bean等。
使用@Autowired
@Autowired
注解主要是按类型(type)自动装配依赖。它可以用在构造器、属性、设置器方法上。
示例1: 构造器注入
java复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired // 在Spring 4.3及之后的版本中,如果该类只有一个构造器,可以省略@Autowired注解
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// UserService的其他方法
}
示例2: 属性注入
java复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
// ProductService的其他方法
}
使用@Resource
@Resource
注解主要是按名称(name)来自动装配依赖。如果没有指定名称,Spring会退回到按类型自动装配。它通常用在属性上,但也可以用在设置器方法上。
示例1: 按名称注入
java复制代码
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@Resource(name = "orderRepository")
private OrderRepository orderRepository;
// OrderService的其他方法
}
示例2: 设置器方法注入
java复制代码
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
@Service
public class CustomerService {
private CustomerRepository customerRepository;
@Resource
public void setCustomerRepository(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
// CustomerService的其他方法
}
实战建议
- 首选构造器注入:构造器注入强制依赖不可为空,提高了类的不变性和测试性。对于必须的依赖,建议使用构造器注入。
- @Autowired和@Qualifier联用:当存在多个同类型的bean需要注入时,
@Autowired
注解可以与@Qualifier
注解联用来精确指定bean的名称。 - 用途区分:如果特定场合需要按名称装配,可以使用
@Resource
;否则,推荐使用@Autowired
以利用其类型安全的特性。 - 减少依赖:尽可能减少对Spring特定注解的依赖,尤其是在编写库代码时。这有助于保持代码的清洁和可移植性。
通过这些示例和建议,你可以根据实际情况和需求,在Spring Boot应用中灵活地使用@Autowired
和@Resource
注解。