返回

搞定@Autowired和@Resource,这些东西别再搞错了!

后端

@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. @Autowiredrequired 属性有什么作用?
A4. required 属性指定是否允许注入失败,默认值为 true。如果设置为 false,则注入失败时不会导致异常。

Q5. @Resourcelookup 属性有什么作用?
A5. lookup 属性指定是否动态查找 Bean,而不是在 bean 构造时注入。这对于延迟注入或延迟绑定很有用。