35. @Autowired和@Resource注解的区别是什么?
大约 3 分钟
在 Spring 框架中,@Autowired
和 @Resource
都可以用于自动注入依赖,但它们的工作机制和使用方式有一些不同。以下是两者的详细比较:
1. @Autowired
注解
- 来源:
@Autowired
是 Spring 自身提供的注解,位于org.springframework.beans.factory.annotation.Autowired
包中。 - 自动注入方式:
@Autowired
默认是按类型(by type)进行自动注入。Spring 容器会查找与被注入字段或方法参数类型匹配的 Bean,并将其注入。 - 使用:
- 可以用在构造函数、方法、字段上。
- 可以与
@Qualifier
注解一起使用,以更精确地指定注入的 Bean。 - 当多个候选 Bean 存在时,可以通过
@Qualifier
注解来指定具体的 Bean。 - 默认情况下,
@Autowired
要求注入的依赖必须存在,如果允许注入的 Bean 可能为null
,可以使用required=false
。
示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class MyService {
@Autowired
private MyRepository myRepository;
// 使用 @Qualifier 来指定注入的具体 Bean
@Autowired
@Qualifier("specificRepository")
private MyRepository specificRepository;
// 构造函数注入
@Autowired
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
2. @Resource
注解
- 来源:
@Resource
是 JSR-250 规范中的注解,位于javax.annotation.Resource
包中,是一种标准的 Java 注解,广泛用于各种 Java 框架中,包括 Spring 和 Java EE。 - 自动注入方式:
@Resource
默认是按名称(by name)进行注入。它首先根据字段名或指定的name
属性查找与之匹配的 Bean。如果按名称没有找到匹配的 Bean,则按类型(by type)进行匹配。 - 使用:
- 可以用在字段或 setter 方法上。
- 可以通过
name
属性明确指定要注入的 Bean 名称。 - 如果没有指定
name
属性,默认使用字段名作为 Bean 的名称来查找 Bean。
示例:
import javax.annotation.Resource;
public class MyService {
// 按名称注入,如果没有指定 name,默认使用字段名作为 Bean 名称
@Resource(name = "myRepository")
private MyRepository myRepository;
// 使用字段名作为 Bean 名称
@Resource
private MyRepository specificRepository;
// setter 方法注入
@Resource
public void setMyRepository(MyRepository myRepository) {
this.myRepository = myRepository;
}
}
3. 总结与区别
- 注解来源:
@Autowired
是 Spring 特有的注解。@Resource
是来自 JSR-250 规范的标准 Java 注解。
- 注入方式:
@Autowired
默认按类型(by type)注入,如果需要按名称注入,可以结合@Qualifier
使用。@Resource
默认按名称(by name)注入,如果找不到匹配的名称,再按类型注入。
- 使用场景:
@Autowired
适合在 Spring 框架内使用,具有更多的灵活性和扩展功能。@Resource
适合与标准 Java 代码或与其他依赖注入框架一起使用,具有更强的兼容性。
- 默认行为:
@Autowired
在没有找到匹配的 Bean 时,会抛出异常,除非设置required=false
。@Resource
在没有找到匹配的 Bean 时,也会抛出异常。
总体来说,@Autowired
更加灵活且与 Spring 框架深度集成,而 @Resource
则是更通用的 Java EE 规范的一部分,适合需要兼容不同 Java 平台或框架的场景。