Java 注解---@Resource 和 @Autowired的区别

文档编写目的
本文主要讲解的是Java就开发中,经常使用的注解的解释和一些使用场景以及会有的坑

我们主要从三个方面来解释:

1. @Resource 和 @Autowired 的区别
2. 开发中使用 @Resource 和 @Autowired 时候,那个最好*
3. 在使用 @Resource 和 @Autowired 进行依赖注入时,可能会遇到以下一些“坑”或需要注意的点

1. @Resource 和 @Autowired 的区别

@Resource 和 @Autowired 是 Spring 框架中用于依赖注入(Dependency Injection, DI)的两个注解,它们都可以帮助我们自动装配 bean 的依赖。尽管它们在目的上相似,但有一些区别和适用场景:
@Resource:

  1. 来源:@Resource 注解并非 Spring 特有的,而是来自 JSR-250 标准,因此可以在非 Spring 环境下使用(如Java EE 应用服务器)。
  2. 类型:@Resource 主要用于按名称(name 属性)来查找和注入 bean。默认情况下,它会尝试匹配字段名或 setter方法名作为 bean 名称。也可以通过指定 name 或 lookup 属性来显式指定 bean 的名称。
  3. 优先级:当同时使用 @Autowired 和 @Resource 注解时,@Resource 的优先级高于 @Autowired。Spring 会先尝试按照 @Resource 的规则进行注入。
  4. 适用场景:当需要明确指定依赖 bean 的名称进行注入时,或者希望在非 Spring 环境下保持注解的一致性时,使用@Resource。

示例

@Resource(name = "userRepository") // 显式指定 bean 名称
private UserRepository userRepository;

@Autowired:

  1. 来源:@Autowired 是 Spring 提供的专用于依赖注入的注解,是 Spring DI 的核心特性之一。
  2. 类型:@Autowired 主要用于按类型(Type)来查找和注入 bean。Spring 会查找与字段或方法参数类型匹配的 bean,并将其注入。如果存在多个同类型的 bean,可以通过指定 @Qualifier 注解配合 @Autowired来指定具体的bean。
  3. 优先级:@Autowired 的优先级低于 @Resource。在没有明确指定名称的情况下,@Autowired 会优先考虑类型匹配。
  4. 适用场景:当依赖注入主要依赖于类型匹配,或者项目完全基于 Spring 构建时,使用 @Autowired。当存在多个同类型 bean 需要通过名称区分注入时,结合 @Qualifier 使用。

示例:

@Autowired
private UserRepository userRepository; // 通过类型匹配注入

@Autowired
public void setUserService(@Qualifier("customUserService") UserService userService) { // 通过 @Qualifier 指定 bean 名称
    this.userService = userService;
}

总结:

  • @Resource 是 JSR-250 标准的一部分,适用于非 Spring 环境,主要按名称注入,也可通过 name 或 lookup属性指定 bean 名称。
  • @Autowired 是 Spring 特有的,主要按类型注入,当存在多个同类型 bean 时,可通过配合 @Qualifier 指定bean 名称。
  • 当同时使用两者时,@Resource 优先级更高。

选择使用哪个注解取决于项目的具体需求、依赖注入的方式(名称还是类型)以及是否需要在非 Spring 环境下兼容。

2. 开发中使用 @Resource 和 @Autowired 时候,那个最好

在实际开发中,选择使用 @Resource 或 @Autowired 并没有绝对的“最好”,因为它们各有特点和适用场景。选择哪一个注解主要取决于以下几个因素:

1. 依赖注入策略

  • 如果你的项目依赖注入主要基于 类型匹配(即依赖项的类型唯一,或者你希望Spring自动按类型找到唯一的bean进行注入),那么@Autowired 更为合适。
  • 如果你的项目依赖注入需要 明确指定bean名称,或者依赖项类型不唯一但名称唯一,那么 @Resource 更符合需求。@Resource
    可以通过 name 属性直接指定bean的名称,或者默认使用字段名或setter方法名作为bean名称。

2. 项目环境:

  • 如果你的项目完全基于 Spring 框架构建,且不需要考虑在非 Spring 环境下的兼容性,那么 @Autowired是一个自然的选择,因为它与 Spring 生态紧密集成,使用广泛。
  • 如果你的项目可能需要在非 Spring 环境(如某些 Java EE 应用服务器)中运行,或者希望代码保持对 JSR-250标准的兼容性,那么 @Resource 由于其跨框架的通用性,可能更为合适。

3. 团队约定与个人习惯

  • 在实际工作中,团队往往会根据项目特点和成员熟悉度,形成统一的依赖注入注解使用规范。遵循团队约定,保持代码风格一致性,有利于代码维护和团队协作。

综上所述
选择 @Resource 或 @Autowired 并无绝对的“最好”,应根据项目实际情况、依赖注入策略、项目环境以及团队约定等因素综合考虑。在大多数Spring项目中,由于其良好的类型匹配机制和广泛的使用,@Autowired 通常更为常见。但如果项目有特殊需求或偏好,@Resource 也是合理的选择。关键在于理解二者差异,合理运用以满足项目需求*

3. 在使用 @Resource 和 @Autowired 进行依赖注入时,可能会遇到以下一些“坑”或需要注意的点

在使用 @Resource 和 @Autowired 进行依赖注入时,可能会遇到以下一些“坑”或需要注意的点:
共同的潜在问题

1. 未定义或未配置依赖项

  • 如果试图注入的 bean 在 Spring 容器中未定义或未正确配置,无论是 @Resource
    还是@Autowired都会导致注入失败。此时,应用程序启动时可能会抛出
    NoSuchBeanDefinitionException或BeanCreationException 等异常。

2. 循环依赖:

  • 当两个或多个 bean 之间形成循环依赖关系时(A 依赖 B,B 又依赖 A),即使使用 @Resource 或@Autowired,也可能导致注入失败或异常。Spring 通过某些策略(如对于单例 bean的部分预初始化)尝试解决循环依赖,但并非所有情况都能成功处理。应尽量避免或重构循环依赖的设计。

3. 未处理的 null 值:

  • 如果注入的 bean 未找到或注入过程中出现异常,字段或方法参数可能会保留为 null。如果不进行适当的 null检查,后续代码可能会触发NullPointerException。在使用依赖注入的字段或方法中,务必做好 null 安全检查。

@Resource 特有的潜在问题

1. 名称匹配不明确

  • 使用 @Resource 时,默认情况下会尝试匹配字段名或 setter 方法名作为 bean 的名称。如果存在多个同名的 bean,或者bean 名称与字段名不一致,可能导致注入失败或注入了错误的 bean。应确保 @Resource 的 name 属性明确指定了正确的bean 名称,或者确保 Spring 容器中的 bean 命名规则清晰、唯一。

2. 与 @Autowired 共存时的优先级问题

  • 如前所述,当同时使用 @Resource 和 @Autowired 注解时,@Resource 的优先级更高。如果配置不当,可能导致预期的 @Autowired注解被忽略。在混合使用这两个注解时,要清楚了解它们的注入顺序和优先级,避免混淆。

@Autowired 特有的潜在问题

1. 类型匹配不唯一:

  • 如果 Spring 容器中有多个同类型(但名称不同)的 bean,@Autowired无法确定注入哪一个,会导致NoUniqueBeanDefinitionException。此时,需要配合 @Qualifier注解明确指定 bean的名称,或者调整 bean 的类型层次结构以避免类型冲突。

2. 未启用组件扫描:

  • 如果依赖的 bean 未通过 context:component-scan 标签或 @ComponentScan
    注解进行组件扫描,Spring 容器可能无法自动发现并注册这些 bean,导致 @Autowired注解无法正常工作。确保已启用组件扫描,或者通过 XML 配置文件手动注册所需 bean。

3. 自动装配与手动配置的混淆:

  • 如果同时使用自动装配(如 @Autowired) 和手动配置(如 XML 文件中的
    标签),可能会导致配置冲突或预期之外的行为。在设计和维护 Spring 配置时,应保持一致性,要么全部采用自动装配,要么全部采用手动配置,避免混用造成混乱。

总结:
通过了解并规避上述潜在问题,可以更有效地使用 @Resource 和 @Autowired 进行依赖注入,降低代码中的注入错误和运行时异常。在实际开发中,定期进行代码审查和自动化测试也能帮助及时发现并修复这些问题。

  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值