展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > @Autowired 与 @Resource 区别详解

@Autowired 与 @Resource 区别详解

@Autowired按类型注入,需@Qualifier或@Primary解决多实例歧义;@Resource优先按名称注入,名称不匹配时按类型,更利于名称明确的场景。

@Autowired按类型注入,需@Qualifier或@Primary解决多实例歧义;@Resource优先按名称注入,名称不匹配时按类型,更利于名称明确的场景。

@Autowired 和 @Resource 注解的区别是什么?

@Autowired 侧重于按类型进行依赖注入,是 Spring 框架特有的;而 @Resource 则优先按名称进行注入,是 Java EE 规范的一部分,可以脱离 Spring 独立使用。

解决方案

理解 @Autowired 和 @Resource 的区别,说到底就是理解它们在查找和匹配依赖时的策略差异。

@Autowired:Spring 的类型优先策略

@Autowired 是 Spring 框架提供的注解,它的核心思想是“按类型装配”(by type)。当你在一个字段、构造器或 Setter 方法上使用 @Autowired 时,Spring 容器会尝试在它管理的 Bean 中找到一个类型匹配的 Bean 来进行注入。

例如:

@Component
public class MyService {
    @Autowired
    private MyRepository myRepository; // Spring会寻找MyRepository类型的Bean
    // ...
}

这里,Spring 会在容器中查找 MyRepository 接口或类的实现。如果容器中只有一个 MyRepository 类型的 Bean,那么它就会被成功注入。但如果容器中有多个 MyRepository 类型的 Bean(比如 MyRepositoryImplA 和 MyRepositoryImplB 都实现了 MyRepository 接口),Spring 就会感到困惑,抛出 NoUniqueBeanDefinitionException 异常,因为它不知道该注入哪一个。

为了解决这种歧义,你可以配合 @Qualifier 注解,明确指定要注入的 Bean 的名称:

@Component
public class MyService {
    @Autowired
    @Qualifier("myRepositoryImplA") // 明确指定Bean的名称
    private MyRepository myRepository;
    // ...
}

或者,你也可以将其中一个实现类标记为 @Primary,告诉 Spring 在有多个相同类型的 Bean 时,优先选择这个:

@Component
@Primary
public class MyRepositoryImplA implements MyRepository { /* ... */ }

@Component
public class MyRepositoryImplB implements MyRepository { /* ... */ }

// MyService中无需@Qualifier,Spring会默认注入MyRepositoryImplA
@Component
public class MyService {
    @Autowired
    private MyRepository myRepository;
    // ...
}

@Resource:Java EE 的名称优先策略

@Resource 注解是 JSR-250 规范的一部分,这意味着它不局限于 Spring 框架,也可以在其他 Java EE 容器(如 Tomcat、Glassfish)中使用。它的默认行为是“按名称装配”(by name)。

当你在一个字段或 Setter 方法上使用 @Resource 时,它的查找顺序是这样的:

  1. 按名称查找: 默认情况下,@Resource 会尝试将注解所在字段的名称(或者 Setter 方法对应的属性名)作为 Bean 的名称去容器中查找。
    @Component
    public class MyService {
        @Resource
        private MyRepository myRepositoryImplA; // 会尝试查找名为"myRepositoryImplA"的Bean
        // ...
    }

    如果找到了,就注入。

  2. 按类型查找: 如果按名称没有找到匹配的 Bean,@Resource 就会退而求其次,尝试按类型进行查找。如果找到一个类型匹配的 Bean,就注入。如果找到多个类型匹配的 Bean,它会抛出异常。

你也可以通过 @Resource 的 name 属性明确指定要注入的 Bean 的名称:

@Component
public class MyService {
    @Resource(name = "myRepositoryImplA") // 明确指定Bean的名称
    private MyRepository myRepository;
    // ...
}

或者通过 type 属性指定类型,但这通常不如 name 属性常用,因为名称匹配是其核心优势:

@Component
public class MyService {
    @Resource(type = MyRepository.class) // 按类型查找
    private MyRepository someRepository;
    // ...
}

总结来说,核心差异是:@Autowired 默认是类型优先,需要 Qualifier 辅助名称;@Resource 默认是名称优先,找不到名称再退化到类型。

Spring Boot开发中,何时优先选择@Autowired,何时选择@Resource?

在 Spring Boot 的日常开发中,选择 @Autowired 还是 @Resource,这其实更多是一种个人习惯和团队规范的体现,当然,也有些场景会让我倾向于某一个。

我个人在多数情况下会更倾向于使用 @Autowired。为什么呢?因为 Spring Boot 项目本身就是深度依赖 Spring 框架的,@Autowired 作为 Spring 原生的注解,用起来感觉更“顺滑”,也更符合 Spring 的设计哲学——即通过类型来建立依赖关系。当我在一个纯粹的 Spring 环境中工作时,我希望我的代码能够充分利用 Spring 提供的便利,而 @Autowired 恰好提供了这种简洁和直观的类型匹配能力。特别是当我的接口只有一个实现类时,@Autowired 几乎是零配置,非常方便。如果遇到多实现的情况,@Qualifier 的存在也提供了一个优雅的解决方案。

然而,在某些特定的场景下,我会发现 @Resource 更有用武之地。比如,当我在处理一些遗留系统,或者与一些第三方库集成时,这些库可能在 Spring 容器中注册了一些名称很明确的 Bean,但它们的类型可能比较通用,或者我只是想通过一个特定的名称来引用它们。这时候,@Resource 的名称优先匹配策略就显得非常直接和清晰,它能够减少潜在的类型匹配混淆。

再比如,如果我需要在代码中显式地通过一个字符串名称来引用一个 Bean(这在某些动态配置或工厂模式中可能会出现),那么 @Resource(name="beanName") 的表达力就比 @Autowired 结合 @Qualifier("beanName") 显得更直接一些,因为它把“按名称注入”这个意图放在了注解本身。

另外,从代码的可移植性角度看,@Resource 因为是 Java EE 规范的一部分,理论上它的代码可以更容易地迁移到其他支持 JSR-250 的 Java EE 容器中。尽管在 Spring Boot 项目中,这种可移植性优势往往被淡化了(因为你已经选择了 Spring),但对于那些对规范性有较高要求,或者未来有潜在迁移需求的项目,@Resource 确实提供了一种更标准化的选择。

所以,我的经验是:对于大多数 Spring Boot 应用的内部组件依赖,@Autowired 是一个非常好的默认选择;而当涉及到与外部系统集成、处理遗留代码、或者需要通过明确名称来消除歧义时,@Resource 会是更稳健和清晰的选择。

如果存在多个相同类型的Bean,这两种注解会如何处理?

处理多个相同类型的 Bean,是我们在 Spring 开发中经常会遇到的一个挑战,也是区分 @Autowired 和 @Resource 行为的关键点。

@Autowired 的处理方式:

当 Spring 容器中存在多个类型相同的 Bean,而你又使用了 @Autowired 进行注入时,如果没有额外的指示,Spring 会感到“不知所措”,因为它不知道应该选择哪一个 Bean。在这种情况下,它会抛出一个 NoUniqueBeanDefinitionException 异常。这个异常会明确告诉你,容器中找到了多个符合类型的 Bean,需要你进行进一步的明确。

为了解决这个问题,通常有以下几种方法:

  1. 使用 @Qualifier: 这是最常用也最推荐的方式。通过在 @Autowired 的同时加上 @Qualifier("beanName"),你可以明确告诉 Spring 要注入哪个具体名称的 Bean。

    @Service("smsSender")
    public class SmsSender implements MessageSender { /* ... */ }
    
    @Service("emailSender")
    public class EmailSender implements MessageSender { /* ... */ }
    
    @Component
    public class NotificationService {
        @Autowired
        @Qualifier("emailSender") // 明确指定注入名为 "emailSender" 的Bean
        private MessageSender messageSender;
    }
  2. 使用 @Primary: 如果你希望在多个相同类型的 Bean 中,有一个是默认优先被注入的,你可以将该 Bean 标记为 @Primary。这样,当 Spring 遇到类型冲突时,会优先选择带有 @Primary 注解的 Bean。

    @Service
    @Primary // 优先选择这个发送器
    public class DefaultSmsSender implements MessageSender { /* ... */ }
    
    @Service
    public class BackupEmailSender implements MessageSender { /* ... */ }
    
    @Component
    public class NotificationService {
        @Autowired // 会自动注入 DefaultSmsSender
        private MessageSender messageSender;
    }
  3. 通过参数名匹配(作为后备): 如果没有 @Qualifier 也没有 @Primary,Spring 还会尝试将要注入的字段名或参数名作为 Bean 的名称进行匹配。但这种方式不如前两种明确,且容易引发混淆,我个人不太推荐在多 Bean 场景下依赖它。

@Resource 的处理方式:

@Resource 在处理多个相同类型的 Bean 时,其行为逻辑有所不同,因为它本身就是名称优先的。

  1. 优先按名称查找: 当你使用 @Resource 注解时,它会首先尝试根据字段名(或 Setter 方法名)来查找 Bean。如果找到了一个名称匹配的 Bean,即使有多个相同类型的 Bean,它也会直接注入这个名称匹配的 Bean,不会引发歧义。

    @Service("smsSender")
    public class SmsSender implements MessageSender { /* ... */ }
    
    @Service("emailSender")
    public class EmailSender implements MessageSender { /* ... */ }
    
    @Component
    public class NotificationService {
        @Resource // 尝试查找名为 "smsSender" 的Bean
        private MessageSender smsSender;
    
        @Resource // 尝试查找名为 "emailSender" 的Bean
        private MessageSender emailSender;
    }
  2. 如果按名称未找到,再按类型查找: 如果 @Resource 没有通过名称找到匹配的 Bean,它才会退而求其次,尝试按类型进行查找。在这种情况下,如果容器中存在多个相同类型的 Bean,并且它们都没有被 @Resource 的名称属性明确指定,那么 @Resource 同样会抛出异常,因为它无法决定注入哪一个。

所以,从处理多 Bean 的角度看,@Resource 在一开始就通过名称匹配的策略,能够在很多情况下避免歧义。而 @Autowired 则需要你显式地通过 @Qualifier 或 @Primary 来解决这种歧义。

从代码可移植性和规范性角度,这两种注解有何优劣?

谈到代码的可移植性和规范性,@Autowired 和 @Resource 确实展现出了不同的哲学和定位。

@Autowired:Spring 框架的深度整合与便捷性

  • 优点:
    • 与 Spring 深度整合: @Autowired 是 Spring 框架的核心组成部分,它与 Spring 的 IoC 容器、AOP、事务管理等功能无缝集成。在纯 Spring 或 Spring Boot 项目中,使用 @Autowired 感觉非常自然,也最能体现 Spring 的“约定优于配置”理念。
    • 简洁性: 对于大多数只有单一实现类的接口,@Autowired 几乎是零配置,代码非常简洁。
    • 类型安全: 默认的类型匹配策略在编译时就能发现一些潜在的类型不匹配问题(当然,运行时找不到 Bean 还是会报错)。
  • 缺点:
    • 框架耦合度高: 这是最主要的“劣势”。@Autowired 是 Spring 特有的注解,如果你的代码将来需要从 Spring 容器迁移到其他非 Spring 的 IoC 容器(比如一个纯 Java EE 容器,或者一个自定义的轻量级容器),那么所有使用了 @Autowired 的地方都需要进行修改。这会增加迁移成本。当然,在实际的 Spring Boot 项目中,这种迁移的可能性通常很低,因为 Spring Boot 本身就意味着对 Spring 生态的深度依赖。
    • 默认行为可能引发歧义: 如前所述,在存在多个相同类型的 Bean 时,@Autowired 默认会报错,需要额外的 @Qualifier 或 @Primary 来解决。

@Resource:Java EE 标准的通用性与规范性

  • 优点:
    • 高可移植性: 这是 @Resource 最显著的优势。作为 JSR-250 规范的一部分,@Resource 是 Java EE 容器的标准注解。这意味着使用了 @Resource 的代码理论上可以在任何支持 JSR-250 的 Java EE 容器中工作,而不仅仅局限于 Spring。对于那些需要考虑跨平台或未来可能迁移到不同容器的场景,@Resource 提供了一层抽象,降低了框架锁定的风险。
    • 规范性: 遵循 Java EE 规范,使得代码在宏观上更具“标准”感,这对于一些对架构规范有严格要求的企业或项目来说可能是一个加分项。
    • 名称优先的清晰性: 其默认的名称匹配策略在很多情况下能够更直观地表达注入意图,尤其是在 Bean 名称具有明确业务含义时。
  • 缺点:
    • 与 Spring 框架的集成不如 @Autowired 紧密: 尽管 Spring 完全支持 @Resource,但它毕竟不是 Spring 原生的。在某些 Spring 特有的高级特性或扩展点上,@Autowired 可能表现得更自然。
    • 在 Spring Boot 环境下,可移植性优势可能被弱化: 就像我前面说的,一旦你选择了 Spring Boot,你通常就已经接受了对 Spring 框架的深度依赖。在这种情况下,@Resource 的可移植性优势在实践中可能并不那么突出。

我的看法:

在我的实际开发经验中,如果项目是全新的 Spring Boot 应用,且不预期有任何脱离 Spring 框架的可能,我通常会选择 @Autowired。它更符合 Spring 的编程模型,也更简洁。然而,如果我正在维护一个老项目,或者一个需要与多种技术栈集成的模块,或者团队对 Java EE 规范有特别的偏好,那么 @Resource 就会成为一个非常有吸引力的选择。它提供了一种更标准化的依赖注入方式,让代码看起来更“规矩”一些,也为未来的不确定性留下了一定的缓冲空间。最终的选择,往往是团队技术栈、项目需求和个人偏好综合权衡的结果。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发 Java
相关文章 更多
精品专题 更多
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

IOS软件

正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

AI

正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

Mac软件 更多
WPS Office macOS版
WPS Office macOS版

WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,

Shapr3D macOS版
Shapr3D macOS版

Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。

REAPER macOS版
REAPER macOS版

REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

Ableton Live macOS版
Ableton Live macOS版

Ableton Live 是面向音乐制作人与现场表演者的数字音频工作站,提供编曲视图、独具特色的现场视图、音频录制、MIDI创作、实时变速、乐器及效果器。Mac版原生支持Apple芯片,并可连接音频接口、MIDI控制器和第三方插件。

Adobe After Effects macOS版
Adobe After Effects macOS版

Adobe After Effects 是面向动态图形、影视特效与视频合成的专业创作软件。它提供关键帧动画、遮罩抠像、运动跟踪、三维空间、文字动画和表达式等工具,并可与 Premiere Pro、Photoshop、Illustrator

Adobe Audition macOS版
Adobe Audition macOS版

Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

Adobe Bridge macOS版
Adobe Bridge macOS版

Adobe Bridge 是面向摄影师、设计师及内容团队的免费数字资产管理工具,可集中预览照片、视频和 Adobe 项目文件,并利用评级、标签、关键词、元数据、筛选与收藏集完成分类检索。它还支持批量重命名、格式导出、相机导入及 Camera

Adobe Illustrator macOS版
Adobe Illustrator macOS版

Adobe Illustrator 是 Adobe 推出的专业矢量图形设计软件,适合在 Mac 上制作标志、图标、插画、包装、信息图及印刷版面。它以路径和锚点构建可无损缩放的图形,并提供钢笔、形状、文字、图像描摹、渐变、画板及生成式功能。

Adobe InDesign macOS版
Adobe InDesign macOS版

Adobe InDesign 是面向印刷品与数字出版物的专业版面设计软件,可在 Mac 上制作书籍、杂志、宣传册、海报、报告及交互式文档。它提供精细的文字样式、网格、母版、长文档管理和印前输出能力。

Adobe Lightroom Classic macOS版
Adobe Lightroom Classic macOS版

Adobe Lightroom Classic 是面向桌面摄影工作流的照片管理与后期处理软件,可将原始照片保存在本地硬盘,通过目录、关键词、评分和收藏夹高效整理图库,并提供 RAW 冲印、蒙版、镜头校正、批量同步及多格式导出等功能。

Adobe Media Encoder macOS版
Adobe Media Encoder macOS版

Adobe Media Encoder 是 Adobe 推出的专业音视频编码与转码工具,可通过队列、预设和监视文件夹批量完成格式转换、代理文件创建及多平台成片输出,并与 Premiere Pro、After Effects 等软件紧密协作。

Adobe Photoshop macOS版
Adobe Photoshop macOS版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理软件,提供图层、蒙版、选区、修复、调色、文字排版、智能对象及生成式编辑等能力。Mac 版支持 Intel 与 Apple Silicon 处理器。

WINDOWS 更多
Adobe Photoshop Windows版
Adobe Photoshop Windows版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理工具,可在 Windows 上完成照片修饰、选区抠图、图层合成、文字排版、绘画及生成式编辑。软件采用订阅授权,由 Creative Cloud 管理安装、更新与许

Adobe InDesign Windows版
Adobe InDesign Windows版

Adobe InDesign 是面向印刷与数字出版的专业页面排版工具,可制作书籍、杂志、宣传册、海报、交互式 PDF 和电子书。它提供精细的文字样式、多页面管理、印前检查及多格式输出能力,并能与 Photoshop、Illustrator

Adobe Illustrator Windows版
Adobe Illustrator Windows版

Adobe Illustrator 是用于绘制矢量图形、插画、图标、徽标和版式的专业设计工具。它以路径和锚点为核心,作品放大后仍能保持清晰,并提供画板、文字、渐变、图像描摹及精确变换等功能,适合品牌视觉、印刷物料、数字界面和商业插画创作。

Adobe Bridge Windows版
Adobe Bridge Windows版

Adobe Bridge 是 Adobe 推出的创意资产管理工具,可集中预览、分类和查找照片、视频、PDF及多种设计文件,并支持元数据、关键词、评级、批量重命名和格式导出。它可与 Photoshop、Illustrator 等应用衔接,

Affinity Photo Windows版
Affinity Photo Windows版

Affinity Photo 是一款面向摄影师、修图师和视觉设计人员的桌面图像编辑工具,提供 RAW 显影、多图层合成、蒙版、实时滤镜、批处理和色彩管理等功能。原独立产品已停止销售,其照片编辑能力已延续至免费的新 Affinity 应用;

Adobe Lightroom Classic Windows版
Adobe Lightroom Classic Windows版

Adobe Lightroom Classic 是面向 Windows 桌面摄影工作流的照片管理与无损编辑工具,可通过目录集中整理大型图库,并完成 RAW 显影、局部蒙版、批量调整、打印和多格式导出。它强调本地文件管理与精细控制,

Figma Windows版
Figma Windows版

Figma 是面向产品设计与开发团队的云端协作平台,可在 Windows 桌面客户端中完成界面绘制、组件管理、交互原型、评论评审和开发交付。文件保存在云端,多名成员能够同步编辑并共享设计系统;官方同时提供免费 Starter 方案及按席位计

Affinity Designer Windows版
Affinity Designer Windows版

Affinity Designer 是面向矢量图形、数字插画和界面设计的专业创作工具,可在矢量、像素与导出工作区之间快速切换。它提供曲线编辑、形状构建、画板、排版、图层和专业色彩管理,并支持常见设计文件的导入及多种印刷、网页格式输出。

Capture One Pro Windows版
Capture One Pro Windows版

Capture One Pro 是面向摄影师和影像团队的专业桌面照片处理工具,提供相机定制色彩配置、RAW转换、图层与蒙版、联机拍摄、目录及会话管理等功能。它适合棚拍、人像、商业产品、婚礼和风光摄影,

Adobe Acrobat Pro Windows版
Adobe Acrobat Pro Windows版

Adobe Acrobat Pro 是面向专业 PDF 工作的综合解决方案,可在 Windows 中创建、编辑、转换、比较、整理和保护文档,并支持表单、电子签名、扫描件文字识别及敏感信息永久遮盖。订阅还包含网页、移动服务和云端协作能力,

Adobe After Effects Windows版
Adobe After Effects Windows版

Adobe After Effects 是面向动态图形、动画与影视视觉特效制作的专业工具,可完成关键帧动画、图层合成、遮罩跟踪、抠像、文字动画和二维三维元素整合。Windows 版通过 Adobe Creative Cloud 安装及更新,

DaVinci Resolve Windows版
DaVinci Resolve Windows版

DaVinci Resolve是Blackmagic Design推出的一体化影视后期工具,将素材管理、非线性剪辑、专业调色、Fusion视觉特效、Fairlight音频处理和成片交付整合在统一工程中。免费版已覆盖多数个人创作需求,