Spring探索——既生@Resource,何生@Autowired?

news2024/11/20 15:40:52

提到Spring依赖注入,大家最先想到应该是@Resource和@Autowired,很多文章只是讲解了功能上的区别,对于Spring为什么要支持两个这么类似的注解却未提到,属于知其然而不知其所以然。不知大家在使用这两个注解的时候有没有想过,@Resource又支持名字又支持类型,还要@Autowired干嘛,难道是Spring官方没事做了?

真的是没事做了吗?读了本文你将会了解到:

  1. @Resource和@Autowired来源
  2. Spring官方为什么会支持这两个功能如此相似的注解?
  3. 为什么@Autowired属性注入的时候Idea会曝出黄色的警告?
  4. @Resource和@Autowired推荐用法

来源

既然要弄清楚,就要先了解他们的身世。

@Resource 于 2006年5月11日随着JSR 250 发布 ,官方解释是:

Resource 注释标记了应用程序需要的资源。该注解可以应用于应用程序组件类,或组件类的字段或方法。当注解应用于字段或方法时,容器将在组件初始化时将所请求资源的实例注入到应用程序组件中。如果注释应用于组件类,则注释声明应用程序将在运行时查找的资源。

可以看到它类似一个定义,而由其他的组件或框架自由实现。

@Autowired 于 2007年11月19日随着Spring2.5发布,同时官方也对@Resource进行了支持。@Autowired的官方解释是:

将构造函数、字段、设置方法或配置方法标记为由 Spring 的依赖注入工具自动装配。

可以看到,@Autowired 是 Spring的亲儿子,而@Resource是Spring对它定义的一种实现,它们的功能如此相似。那么为什么要支持了@Resource,又要自己搞个@Autowired呢?

对此专门查了一下Spring2.5的官方文档,文档中有一段这么说到:

However, Spring 2.5 dramatically changes the landscape. As described above, the autowiring choices have now been extended with support for the JSR-250 @Resource annotation to enable autowiring of named resources on a per-method or per-field basis. However, the @Resource annotation alone does have some limitations. Spring 2.5 therefore introduces an @Autowired annotation to further increase the level of control.

大概的意思是说,Spring2.5 支持注解自动装配啦, 现已经支持JSR-250 @Resource 基于每个方法或每个字段的命名资源的自动装配,但是只有@Resource是不行的,我们还推出了“粒度”更大的@Autowired,来覆盖更多场景了。

嗯哼,那么官方说的“粒度”就是关键了,那“粒度”指的是什么呢”?

既生“@Resource”,何生“@Autowired”

要想找到粒度是什么,我们先从两个注解的功能下手

@Autowired

  • 类型注入

@Resource

  • 名字注入优先,找不到名字找类型

论功能的“粒度”,@Resource已经包含@Autowired了啊,“粒度”更大啊,难道是Spring2.5的时候还不是这样?我又去翻了下Spring2.5文档,上面明确的写到:

When using @Resource without an explicitly provided name, if no Spring-managed object is found for the default name, the injection mechanism will fallback to a type-match.

这不是和现在一样的吗,我此时凌乱了。那么“粒度”到底指的是什么?在混迹众多论坛后,其中stackoverflow的一段话引起了我的注意:

Both @Autowired and @Resource work equally well. But there is a conceptual difference or a difference in the meaning.

  • @Resource

    means get me a known resource by name. The name is extracted from the name of the annotated setter or field, or it is taken from the name-Parameter.

  • @Inject

    or

    @Autowired

    try to wire in a suitable other component by type.

So, basically these are two quite distinct concepts. Unfortunately the Spring-Implementation of @Resource has a built-in fallback, which kicks in when resolution by-name fails. In this case, it falls back to the @Autowired-kind resolution by-type. While this fallback is convenient, IMHO it causes a lot of confusion, because people are.

大概的意思是:Spring虽然实现了两个功能类似的,但是存在概念上的差异或含义上的差异:

  • @Resource 这按名称给我一个确定已知的资源。
  • @Autowired 尝试按类型连接合适的其他组件。

但是@Resource当按名称解析失败时会启动。在这种情况下,它会按类型解析,引起概念上的混乱,因为开发者没有意识到概念上的差异,而是倾向于使用@Resource基于类型的自动装配。

原来Spring官方说的“粒度”是指“资源范围”,@Resource找寻的是确定的已知的资源,相当于给你一个坐标,你直接去找。@Autowired是在一片区域里面尝试搜索合适的资源。

所以上面的问题答案已经基本明确了。

Spring为什么会支持两个功能相似的注解呢?

  • 它们的概念不同,@Resource更倾向于找已知资源,而Autowired倾向于尝试按类型搜索资源。
  • 方便其他框架迁移,@Resource是一种规范,只要符合JSR-250规范的其他框架,Spring就可以兼容。

既然@Resource更倾向于找已知资源,为什么也有按类型注入的功能?

  • 个人猜测:可能是为了兼容从Spring切换到其他框架,开发者就算只使用Resource也是保持Spring强大的依赖注入功能。

Spring的区别对待

看到这相信大家对使用@Resource还是@Autowired有了自己的见解。在日常写代码中有个小细节不知道大家有没有注意到,使用@Autowired在属性上的时候Idea会曝出黄色的警告,并且推荐我们使用构造方法注入,而Resource就不会,这是为什么呢?警告如下:

图片

为什么@Autowired在属性上的时候Idea会曝出黄色的警告,并且推荐我们使用构造方法注入?

其实Spring文档中已经给出了答案,主要有这几点:

1、声明不了常量的属性

基于属性的依赖注入不适用于声明为 final 的字段,因为此字段必须在类实例化时去实例化。声明不可变依赖项的唯一方法是使用基于构造函数的依赖项注入。

2、容易忽视类的单一原则

一个类应该只负责软件应用程序功能的单个部分,并且它的所有服务都应该与该职责紧密结合。如果使用属性的依赖注入,在你的类中很容易有很多依赖,一切看起来都很正常。但是如果改用基于构造函数的依赖注入,随着更多的依赖被添加到你的类中,构造函数会变得越来越大,代码开始就开始出现“异味”,发出明确的信号表明有问题。具有超过十个参数的构造函数清楚地表明该类有太多的依赖,让你不得不注意该类的单一问题了。因此,属性注入虽然不直接打破单一原则,但它却可以帮你忽视单一原则。

3、循环依赖问题

A类通过构造函数注入需要B类的实例,B类通过构造函数注入需要A类的实例。如果你为类 A 和 B 配置 bean 以相互注入,使用构造方法就能很快发现。

4、依赖注入强依赖Spring容器

如果您想在容器之外使用这的类,例如用于单元测试,不得不使用 Spring 容器来实例化它,因为没有其他可能的方法(除了反射)来设置自动装配的字段。

为什么@Resource没有呢?

在官方文档中,我没有找到答案,查了一些资料说是:@Autowired 是 Spring 提供的,一旦切换到别的 IoC 框架,就无法支持注入了. 而@Resource 是 JSR-250 提供的,它是 Java 标准,我们使用的 IoC 容器应该和它兼容,所以即使换了容器,它也能正常工作。

@Autowired和@Resource推荐用法

1. 什么场景用什么合适

记住一句话就行,@Resource倾向于确定性的单一资源,@Autowired为类型去匹配符合此类型所有资源

如集合注入,@Resource也是可以的,但是建议使用@Autowired。idea左侧的小绿标可以看出来,不建议使用@Resource注入集合资源,本质上集合注入不是单一,也是不确定性的。

图片

2. @Autowired推荐用法

方法1 :使用构造函数注入(推荐)

原生版:

图片

优雅版:使用lombok的@RequiredArgsConstructor+private final

图片

方法2:set注入

原生版:

图片

优雅版:使用lombok的@Setter

图片

简单总结一下 @Autowired和@Resource 区别:

  • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
  • Autowired 默认的注入方式为byType(根据类型进行匹配),可以配合@Qualifier 实现 byName 匹配。默认注入的值必须存在,否则报错。除非required = false
  • @Resource默认注入方式为 byName(根据名称进行匹配),如果byName没有则按照byType匹配,默认注入的值不存在,不会报错。
  • 当一个接口存在多个实现类的情况下,@Autowired@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql8.0主从复制搭建

mysql8.0主从复制搭建 1.安装两个相同版本8.0的mysql数据库 主从IP端口主库192.168.139.1283306从库192.168.139.1303306 2.主从复制配置 2.1 修改mysql配置文件my.conf 主机mysql配置完整 [mysql] # 设置mysql客户端默认字符集 default-character-setutf8mb4 [client] # …

二十三种设计模式第十篇--外观模式

在现实生活中,常常存在办事较复杂的例子,如办房产证或注册一家公司,有时要同多个部门联系,这时要是有一个综合部门(政务窗口 )能解决一切手续问题就好了。 软件设计也是这样,当一个系统的功能越来越强&…

2023年小型水库安全监测能力提升解决方案

一、方案背景 2023年小型水库安全监测能力提升试点项目建设将按照“统一规划、统一标准、统一实施、统一管理、统一支撑”的工作要求,对全区小型水库雨水情测报和监测设施建设项目按高水平、高标准、高质量要求开展安全监测能力提升建设,同步开展水工程安…

ZeLinAI是什么?国产ChatGPT快速搭建自己的AI应用

ChatGPT使用门槛高,需要科学上网短信接码等,不如直接选择国产ZelinAI,使用超简单轻轻松松从0到1零代码创建自己的AI应用。目前模型仅支持GPT-3.5-turbo,后续应该会接入文心一言、GPT-4、GPT-4.5和Bard,新手站长分享国产…

DL.to 最新研究(论文)推荐——分割、CVPR、扩散模型、感受野注意力模块

目录 一、CVPR 1.CrowdCLIP:基于视觉-语言模型的无监督人群计数 CrowdCLIP: Unsupervised Crowd Counting via Vision-Language Model 2.Beyond mAP:更好地评估实例分割 Beyond mAP: Re-evaluating and Improving Performance in Instance Segmentation with Se…

基于低代码平台的多租户解决方案

在云计算时代,“多租户”是一个非常重要的概念。根据百度百科中的定义,多租户技术是一种软件架构技术,简单来说是指以单一系统架构与服务提供多数客户端相同甚至可定制化的服务,并且仍然可以保障客户的数据在多租户环境中&#xf…

Redis之bitmap/hyperloglog/GEO

Redis之bitmap/hyperlog/GEO 一 面试题引入二 统计的类型三 hyperloglog3.1 行业术语3.2 hyperloglog基础3.2.1 基数3.2.2 定义3.2.3 基数统计3.2.4 基本命令 3.3 HyperLogLog原理3.3.1 去重复统计的方式3.3.2 原理 3.4 HyperLogLog案例实战3.4.1 需求3.4.2 方案讨论3.4.3 Hype…

五、SpringMVC从入门到入坟

一、SpringMVC概念 SpringMVC 是 Spring 框架中的一个模块,它是一个基于 MVC设计模式的 Web 框架,用于构建基于 Java 技术的 Web 应用程序。Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。 它的主要原理是将 Web 应用程序分成模型&…

实时频谱-2.4窗口函数

窗口函数 在离散傅立叶变换(DFT)分析运算中,一个固有的假设是要处理的数据是单个周期定期重复的信号。例如,在图2-8中的帧2上应用DFT处理时,信号上会进行周期性扩展。 在连续的帧之间一般会发生不连续点,如图 2-9 所示。 这些人…

平板电脑哪种电容笔更好用?平价好用的iPad电容笔推荐

我是一个非常喜欢数码产品的发烧者,多少了解一些关于电容笔的知识。我想,苹果原装的电容笔与普通的电容笔的不同之处就是他们所能产生的压力感觉不同。由于苹果的电容笔拥有独一无二的“重力压感”,使得它可以让我们在一幅画面中快速填充色彩…

Docker笔记8 | Docker内部以及容器之间如何管理数据?

8 | Docker内部以及容器之间如何管理数据? 1 数据卷1.1 什么是数据卷?1.2 数据卷的特性1.3 创建数据卷1.4 查看数据卷1.5 启动挂在数据卷的容器1.6 删除数据卷 2 挂在主机目录2.1 挂载主机目录作为数据卷2.2 查看数据卷信息2.3 挂载本地主机文件作为数据…

深度学习基础入门篇-序列模型[11]:循环神经网络 RNN、长短时记忆网络LSTM、门控循环单元GRU原理和应用详解

【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化…

中原雄狮官网上线 | LTD物流服务行业案例分享

​一、公司介绍 中原雄狮崛起于2017年,彼时,全国货运行业存在许多不良行为,无赖货主和黑心货站恶意拖欠货车司机运费,而货车司机作为弱势群体却势单力薄无依无助的问题,为了让司机的血汗钱能颗粒归仓,中原雄…

一个活人的标准:灵·魂·身体到底是咋回事儿

正常情况 人类对自我的探求一直没有减弱过,总是在发现并给我们带来惊喜。今天也通过神赐给我们的圣经来跟大家分享一下灵魂身体之间的关系。 神创造了人,并给了人独一的灵。所以人是万物的灵长,比任何生物都聪明。一个“活人”必须要有的就是…

计算机图形学 | 有趣的测试和合并——片元操作

计算机图形学 | 有趣的测试和合并——片元操作 计算机图形学 | 有趣的测试和合并——片元操作10.1 再看片元操作片元操作几个重要的缓冲区 10.2 谁遮住了我?消隐的概念面剔除深度测试深度缓冲器算法(Z-buffer算法)深度排序算法(de…

新华三发布绿洲平台3.0,五大能力升级,构筑坚实用数底座

当前我国数字经济飞速发展,据中国信息通信研究院发布的《中国数字经济发展研究报告(2023年)》显示,2022年,我国数字经济规模达到50.2万亿元,同比名义增长10.3%,已连续11年显著高于同期GDP名义增…

HTTP协议概述(见过花开就好了,何必在意花落谁家呢)

文章目录 一、简介二、HTTP版本三、HTTP 方法四、HTTP状态码五、HTTP 请求流程分析1.请求报文2.响应报文 一、简介 客户端输入域名,经域名解析成IP地址,在与服务端建立数据传输之前,要先建立TCP连接(三次握手)&#x…

Day03 02-MySQL多表查询详解

文章目录 第八章 多表查询8.1 多表查询介绍8.1.1 什么是多表查询8.1.2 多表查询基本写法8.1.3 笛卡尔积8.1.4 连接查询条件限制 8.2 连接查询分类8.2.1 内连接8.2.2 外连接8.2.3 全连接8.2.4 自然连接 8.3 子查询8.3.1 子查询简介8.3.2 在where子句中8.3.3 在from子句中8.3.4 在…

是德科技keysight E8257D信号发生器

产品概览 Keysight E8257D (Agilent) PSG 模拟信号发生器提供业界领先的输出功率、电平精度和高达 67 GHz 的相位噪声性能(工作频率可达 70 GHz)。Agilent PSG 模拟信号发生器的高输出功率和卓越的电平精度通常无需使用外部放大器来测试高功率设备&…

国内热门AI智能音箱品牌都采用了哪些功放芯片

音频功放IC是各类音响、耳机等器材不可或缺的一部分;音频功率放大器芯片俗称“扩音器”,是音响系统中最基本的设备,负责将来自信号源的微弱电信号进行放大,以驱动扬声器发声,从而将声音传至我们的听觉系统。 现如今&a…