搞定@Autowired和@Resource,这些东西别再搞错了!
2023-11-14 18:12:49
@Autowired 与 @Resource:Spring 依赖注入注解的对比
在 Java 的 Spring 框架中,@Autowired
和 @Resource
都是用于依赖注入的重要注解。它们的作用都是将其他 Bean 注入到目标 Bean 中,但它们的用法和一些特性存在差异。本文将深入探讨这两个注解之间的区别,帮助读者在使用 Spring 进行依赖注入时做出明智的决策。
1. 查找机制
@Autowired
优先通过类型匹配来查找要注入的 Bean。如果存在多个匹配的 Bean,它会根据字段名称或 setter 方法名称进一步缩小范围。
另一方面,@Resource
可以通过名称或类型来查找 Bean。默认情况下,它会使用字段或 setter 方法的名称作为 Bean 名称。但是,可以使用 name
属性显式指定 Bean 名称。
2. 装配顺序
@Autowired
在 bean 构造之后进行装配,在 @PostConstruct
方法之前。它通过反射直接向属性赋值。
@Resource
则在 bean 构造之前进行装配,在 @PreDestroy
方法之后。它通过 setter 方法来注入 Bean。
3. 作用域
@Autowired
的作用域是整个 Spring 容器,这意味着它可以在容器中的任何地方注入 Bean。
@Resource
的作用域是当前类及其子类,这意味着它只能注入当前类或其子类中的 Bean。
4. 默认值
@Autowired
的默认值是 "autowire"
,这意味着它根据类型或名称匹配自动查找 Bean。
@Resource
的默认值是 "name"
,这意味着它优先根据名称查找 Bean。
5. 兼容性
@Autowired
与 JSR-330 标准的 @Inject
注解兼容,这意味着它也可以用于非 Spring 环境中。
@Resource
则是一个 Spring 特定的注解,不能在非 Spring 环境中使用。
6. 使用场景
根据这些差异,@Autowired
通常用于注入 Spring 容器中范围更广的 Bean,例如服务或 DAO。而 @Resource
则更适合注入当前类或其子类中的 Bean,例如依赖项或工具类。
代码示例
使用 @Autowired 注入 Bean:
@Autowired
private MyService myService;
使用 @Resource 注入 Bean:
@Resource(name = "myService")
private MyService myService;
7. 注意避免的误用
- 避免同时使用
@Autowired
和@Resource
为同一个属性注入 Bean,这可能会导致混淆和异常。 - 避免使用这些注解注入非 Spring Bean,这也会导致异常。
- 避免使用这些注解注入集合或循环依赖,这会导致注入失败。
8. 结论
@Autowired
和 @Resource
都是 Spring 中常用的依赖注入注解,但它们有着不同的特性和用法。通过理解它们的差异,开发人员可以做出明智的选择,以满足他们的特定需求。
9. 常见问题解答
Q1. 为什么不能同时使用 @Autowired
和 @Resource
?
A1. 同时使用这两个注解可能会导致 Spring 容器无法确定哪个注解的优先级更高,从而导致异常。
Q2. 什么时候应该使用 @Resource
?
A2. 当需要根据名称或在当前类或其子类中注入 Bean 时,应该使用 @Resource
。
Q3. @Autowired
和 @Resource
如何处理循环依赖?
A3. 这两个注解都不能处理循环依赖,这会导致异常。
Q4. @Autowired
的 required
属性有什么作用?
A4. required
属性指定是否允许注入失败,默认值为 true
。如果设置为 false
,则注入失败时不会导致异常。
Q5. @Resource
的 lookup
属性有什么作用?
A5. lookup
属性指定是否动态查找 Bean,而不是在 bean 构造时注入。这对于延迟注入或延迟绑定很有用。