Spring 依赖注入:@Resource vs @Autowired,傻傻分不清?

在 Spring 框架中,依赖注入 (Dependency Injection, DI) 是一种核心的设计模式,它允许我们以松耦合的方式管理对象之间的依赖关系。 Spring 提供了多种方式来实现依赖注入,其中最常用的两种方式是使用 @Resource 和 @Autowired 注解。 那么,这两个注解有什么区别呢? 什么时候应该使用哪个注解呢? 本文将深入探讨这两个注解的区别,帮助你更好地理解和使用它们。

1. 来源:出身不同,使命各异

  • @Autowired:Spring 家族的嫡系子弟

    @Autowired 注解来自 Spring 框架本身 (org.springframework.beans.factory.annotation.Autowired)。 它是 Spring 容器管理的 bean 的最佳选择,能够充分利用 Spring 框架的各种特性。

  • @Resource:Java EE 标准的通用人才

    @Resource 注解则来自 JSR-250 规范 (javax.annotation.Resource)。 JSR-250 是 Java EE 的一个标准规范,这意味着 @Resource 不仅可以在 Spring 中使用,也可以在其他支持 JSR-250 规范的容器中使用,具有更广泛的适用性。

2. 注入方式:按图索骥,各有侧重

  • @Autowired:类型匹配优先,名称匹配为辅

    @Autowired 默认情况下按照 类型 (byType) 查找依赖对象。 也就是说,Spring 容器会查找与被注解的属性类型相同的 bean。 如果找到多个相同类型的 bean,@Autowired 会尝试按照 名称 (byName) 进行匹配,即查找与属性名称相同的 bean。 如果仍然找到多个匹配的 bean,或者根本没有找到匹配的 bean,Spring 就会抛出异常。

    为了解决找到多个匹配 bean 的问题,我们可以使用 @Qualifier 注解来指定要注入的 bean 的名称,就像给 @Autowired 提供了更精确的 "搜索条件"。

  • @Resource:名称匹配优先,类型匹配为辅

    @Resource 的策略则恰好相反。 它默认按照 名称 (byName) 查找依赖对象。 Spring 容器会查找与被注解的属性名称相同的 bean。 如果找不到与属性名称匹配的 bean,@Resource 才会尝试按照 类型 (byType) 进行匹配。 我们可以使用 name 属性来显式指定要注入的 bean 的名称,就像给 @Resource 提供了 "寻宝图"。

3. 适用场景:术业有专攻,各有所长

  • @Autowired:Spring Bean 的最佳搭档

    @Autowired 更适合注入 Spring 容器管理的 bean。 它是 Spring 自己的注解,能够与 Spring 的各种特性无缝集成,例如 AOP、事件机制等。

  • @Resource:JNDI 资源的得力助手

    @Resource 更适合注入 JNDI 资源 (例如数据源、消息队列等)。 由于它是 Java EE 的标准注解,可以更好地与 Java EE 容器集成。 当然,@Resource 也可以用于注入 Spring 容器管理的 bean,但不如 @Autowired 那么 "原生"。

4. 其他差异:细节决定成败

特性@Autowired@Resource
来源SpringJSR-250 (Java EE)
注入方式默认 byType, 找不到时 byName, 可用 @Qualifier 指定默认 byName, 找不到时 byType, 可用 name 属性指定
适用场景Spring 容器管理的 beanJNDI 资源, Spring 容器管理的 bean
默认 requiredtrue, 可设置 falsetrue, 可设置 false
注入位置构造器, setter 方法, 字段setter 方法, 字段
  • Required 属性: 两个注解都提供了 required 属性,用于指定依赖对象是否必须存在。 默认情况下,required 属性都为 true,即依赖对象必须存在。 如果找不到依赖对象,Spring 容器会抛出异常。 我们可以将 required 属性设置为 false,允许依赖对象为 null
  • 注入位置: @Autowired 可以用于构造器、setter 方法和字段上,更加灵活。 当用于构造器上时,如果只有一个构造器,则可以省略 @Autowired 注解。 @Resource 只能用于 setter 方法和字段上。

5. 最佳实践:因地制宜,灵活选择

那么,在实际开发中,我们应该如何选择使用 @Resource 和 @Autowired 呢?

  • 优先考虑 @Autowired 如果你的项目只使用 Spring 框架,并且只需要注入 Spring 容器管理的 bean,那么优先考虑使用 @Autowired。 它可以更好地利用 Spring 框架的特性,并且更加简洁明了。
  • 注入 JNDI 资源时使用 @Resource 如果你的项目需要与 Java EE 容器集成,或者需要注入 JNDI 资源,那么使用 @Resource 可能会更合适。
  • 明确指定 bean 的名称: 为了避免歧义,建议在使用 @Autowired 和 @Resource 时,都明确指定要注入的 bean 的名称。 对于 @Autowired,可以使用 @Qualifier 注解;对于 @Resource,可以使用 name 属性。
  • 保持代码风格一致: 在同一个项目中,尽量保持代码风格一致,选择一种你喜欢的风格,并坚持使用它。

6. 示例代码:一码胜千言

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.Resource;

public class MyService {

    // 使用 @Autowired 按照类型注入
    @Autowired
    private MyRepository myRepository;

    // 使用 @Autowired 和 @Qualifier 按照名称注入
    @Autowired
    @Qualifier("myOtherRepository")
    private MyRepository myOtherRepository;

    // 使用 @Resource 按照名称注入
    @Resource(name = "myRepository")
    private MyRepository myRepository2;

    // 使用 @Resource 按照类型注入 (不推荐,容易出错)
    @Resource
    private MyRepository myRepository3;

    public void doSomething() {
        myRepository.doSomething();
        myOtherRepository.doSomething();
        myRepository2.doSomething();
        myRepository3.doSomething();
    }
}

展开

在上面的示例中,myRepositorymyOtherRepository 和 myRepository2 都被成功注入了 MyRepository 类型的 bean。 myRepository3 的注入可能会出错,因为 Spring 容器中可能存在多个 MyRepository 类型的 bean,导致无法确定要注入哪个 bean。

7. 总结:选择适合自己的才是最好的

@Resource 和 @Autowired 都是 Spring 框架中用于依赖注入的强大工具。 它们各有优缺点,适用于不同的场景。 在选择使用哪个注解时,应该根据你的具体需求和项目环境来决定。 记住,理解它们的区别,才能更好地运用它们,编写出更清晰、更健壮的代码。

希望本文能够帮助你更好地理解 @Resource 和 @Autowired 的区别,并在实际开发中做出更明智的选择! 感谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值