面试问到Spring中的@Autowired注解,可以这样答

前言

在Spring框架中,依赖注入是一个核心概念,它允许将一个对象的依赖关系外部化并由Spring容器来管理。@Autowired注解是实现这一点的关键工具之一。当然,这块知识也是面试官们老生常谈的问题。

下面就跟着博主的步伐,一起来探讨@Autowired注解相关知识点吧!

在这里插入图片描述

@Autowired注解基础

@Autowired注解可以用于构造函数、setter方法、字段以及配置方法上,以指示Spring自动注入相应的bean。它的工作原理基于类型匹配,Spring容器会查找与所需类型匹配的bean,并自动注入。

字段注入

@Component  
public class MyComponent {  
    @Autowired  
    private MyDependency dependency;  
}

构造函数注入

在写代码时,博主推荐的做法是使用构造函数注入,因为它可以使类更易于测试,并且确保了依赖项在对象创建时就已经设置。

@Component  
public class MyComponent {  
    private final MyDependency dependency;  
  
    @Autowired  
    public MyComponent(MyDependency dependency) {  
        this.dependency = dependency;  
    }  
}

Setter方法注入

虽然setter注入不如构造函数注入受欢迎,但在某些情况下,它可能是必要的。

@Component  
public class MyComponent {  
    private MyDependency dependency;  
  
    @Autowired  
    public void setDependency(MyDependency dependency) {  
        this.dependency = dependency;  
    }  
}

解析流程与原理

当Spring容器启动时,它会扫描所有标注了@Component(或其派生注解如@Service, @Repository, @Controller等)的类,并创建相应的bean定义。当遇到@Autowired注解时,Spring会查找匹配的bean来注入

匹配规则基于类型。比如,如果有一个类型为MyDependency的字段标注了@Autowired,Spring会查找类型为MyDependency的bean进行注入。如果有多个匹配的bean,则需要使用@Qualifier注解来指定具体的bean

相同Bean的案例分析:多例与冲突解决

当Spring容器中存在多个相同类型的bean时,使用@Autowired可能会导致冲突。比如下面的场景:

假设我们有两个实现了同一个接口的bean:

@Component("firstBean")  
public class FirstBean implements MyInterface { /*...*/ }  
  
@Component("secondBean")  
public class SecondBean implements MyInterface { /*...*/ }

如果我们在另一个组件中尝试自动装配这个接口的实例:

@Component  
public class MyComponent {  
    @Autowired // 这里会发生什么?  
    private MyInterface myInterface;  
}

在这种情况下,Spring会抛出NoUniqueBeanDefinitionException,因为它不清楚应该注入哪一个实现。为了解决这个问题,我们可以使用@Qualifier注解来指定具体的bean名称:

@Component  
public class MyComponent {  
    @Autowired  
    @Qualifier("firstBean") // 指定要注入的bean名称  
    private MyInterface myInterface;  
}

另一种解决方法是使用Java配置或XML配置来显式声明bean的关系

@Autowired和@Resource注解的区别

这种问法也是面试官经常问到的典型问题!接下来详细介绍一下这块知识点。

首先是它们的依赖查找方式不同。

  • @Autowired默认按照类型(byType)进行自动装配的。上文提到过,如果存在多个相同类型的bean,需要配合@Qualifier注解来指定bean的名称(byName),或者确保需要注入的字段、方法参数或构造函数参数是唯一的。
  • @Resource默认按照名称(byName)进行装配,它会查找与指定名称相同的bean。如果找不到匹配的bean,它会退回到按照类型(byType)进行查找。So,@Resource可以指定名称(通过name属性)和类型(通过type属性,但通常不需要指定,因为Java编译器会推断出类型)。

同时,它们的使用方式也有所不同。

@Autowired可以标注在构造器、方法、参数、字段上,以支持构造器注入、setter注入和字段注入。
而@Resource也可以标注在字段和方法上,但通常更常见于字段注入。

对于强制依赖问题,他们的表现如下:

@Autowired有一个required属性,默认为true,表示被注入的bean是必需的。如果找不到匹配的bean,Spring容器在启动时会抛出异常。当设置为false时,如果找不到bean,则不会报错,但相关字段会被设置为null。
@Resource没有直接提供类似的属性,但可以通过Java的@Nullable注解来标明某个字段可以为null。

总结与最佳实践

博主在此做个小结,各位小伙伴们记住了哟:

  • 优先使用构造函数注入,因为它更加不可变且易于测试。
  • 当存在多个匹配的bean时,使用@Qualifier来消除歧义。
  • 尽量避免在字段上使用@Autowired,因为这会使代码更难以理解和测试;应该考虑使用构造函数或setter方法注入。

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Three.js是基于原生WebGL封装的三维引擎

Three.js: 基于原生WebGL封装的三维引擎 引言 随着互联网技术的发展,Web前端技术不断进步,用户对于网页交互体验的要求也越来越高。艾斯视觉前端开发:三维技术作为提升用户体验的重要手段之一,正在逐渐成为前端开发中的热门技术…

PyTorch张量索引用法速查

作为数据科学家或软件工程师,你可能经常处理大型数据集和复杂的数学运算,这些运算需要高效且可扩展的计算。PyTorch 是一个流行的开源机器学习库,它通过 GPU 加速提供快速灵活的张量计算。在本文中,我们将深入研究 PyTorch 张量索…

纷享销客当选江西省数字经济学会首席信息官专业委员会副主任委员

5月11日,江西省数字经济学会首席信息官(CIO)专业委员会成立大会暨“新质生产力”企业数字化转型论坛在南昌香格里拉大酒店隆重举行。 江西省工业和信息化厅作为指导单位,由江西省数字经济学会、南昌市中小企业服务局主办,金蝶软件&#xff0…

单值二叉树(oJ题)

一、题目连接:. - 力扣(LeetCode) 二、题目思路 遍历左右子树,如果左子树存在不为空并且根结点的值不等于左子树的值,返回false, 如果右子树存在不为空并且根结点的值不等于右子树的值,返回false, 每一个…

了解VS安全编译选项GS

缓冲区溢出攻击的基本原理就是溢出时覆盖了函数返回地址,之后就会去执行攻击者自己的函数; 针对缓冲区溢出时覆盖函数返回地址这一特征,微软在编译程序时使用了安全编译选项-GS; 目前版本的Visual Studio中默认启用了这个编译选项…

MT2075 礼物

思路: x,y为质数,若x2,y3,则xy的最小公倍数6既不能给A也不能给B。 所以假设共有V个数,在1-V中,可以选的个数为:V-⌊V/(x*y)⌋ 个。(⌊V/(x*y)⌋为V个数中有多少个xy的公倍数) 所以…

Kibana使用教程

Kibana使您能够轻松地向Elasticsearch发送请求,并以交互方式分析、可视化和管理数据。 1.安装 1.1 docker安装Kibana 如果你还没安装Elasticsearch,先执行docker安装Elasticsearch,下面是单机部署。 创建一个ES网络: docker n…

信息系统项目管理师0137:输出(8项目整合管理—8.9结束项目或阶段—8.9.3输出)

点击查看专栏目录 文章目录 8.9.3 输出8.9.3 输出 项目文件(更新)可在结束项目或阶段更新所有项目文件,并标记为最终版本。特别值得注意的是,经验教训登记册的最终版本要包含阶段或项目收尾的最终信息。最终版本的经验教训登记册可包含:效益管理、项目评估的准确性、项目和…

Spring和Servlet的整合

Servlet对象是谁创建的? 由服务器端创建的 程序启动调用加载spring配置文件代码 Web应用程序启动也需要加载Spring配置文件 Web开发中有三大组件: 1、servlet 2、filter 3、listener(request,session,application&…

(4)医疗图像处理:MRI磁共振成像-成像技术--(杨正汉)

目录 一、特殊成像技术 1.水成像技术 2.化学位移成像技术 二、成像辅助技术 1.脂肪抑制技术 2.磁化转移技术 3.流动补偿技术 4.空间饱和空间标记技术 5.生理门控及导航回波技术 所有的这些技术最终就是为了使得K空间通过傅里叶变化之后得到的图片变的更为清晰。 一、…

React Hooks是如何保存的

React 函数式组件是没有状态的,需要 Hooks 进行状态的存储,那么状态是怎么存储的呢?Hooks是保存在 Fiber 树上的,多个状态是通过链表保存,本文将通过源代码分析 Hooks 的存储位置。 创建组件 首先我们在组件中添加两…

Nocobase快速上手 - 常见block的使用

在上一篇文章 Nocobase快速上手 -第一个collection 中,我们新建了一个collection ,并且通过在页面中配置block实现了数据的展示,本文继续探索block的使用。 Block类型 Block(区块)的整体架构如下图: 我们可以看到,block分为三个大类&#…

文心智能体平台 | 想象即现实

目录 文心智能体平台介绍平台简介通过平台能做什么平台的优势智能体介绍智能体类型AI 插件介绍 动手创建一个智能体访问平台并进行账号注册根据适合的方式选择智能体类型快速创建智能体智能体个性化模块配置 总结注意事项我的智能体 文心智能体平台介绍 平台简介 文心智能体平…

用Python实现办公自动化

💂 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】🤟 一站式轻松构建小程序、Web网站、移动应用:👉注册地址🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交…

【第五节】C++的多态性与虚函数

目录 前言 一、子类型 二、静态联编和动态联编 三、虚函数 四、纯虚函数和抽象类 五、虚析构函数 六、重载,重定义与重写的异同 前言 面向对象程序设计语言的三大核心特性是封装性、继承性和多态性。封装性奠定了基础,继承性是实现代码重用和扩展…

AC/DC电源模块:可靠持久的能源供应

BOSHIDA AC/DC电源模块:可靠持久的能源供应 AC/DC电源模块是一种被广泛应用于工业、通信、医疗等领域的电源设备。其可靠持久的能源供应能够保证设备的正常运行和稳定性能,具有重要的意义。在本文中,我们将详细介绍AC/DC电源模块的特点和优势…

实用新型专利申请被驳回原因

实用新型专利作为知识产权的重要组成部分,对推动技术创新和产业发展具有重要意义。然而,在申请实用新型专利的过程中,有时会遇到被驳回的情况。 实用新型专利被驳回的一个常见原因是技术方案不具备新颖性、创造性和实用性等专利授权条件。专利…

Vue从入门到实战Day12~14 - Vue3大事件管理系统

一、用到的知识 Vue3 compositionAPIPinia / Pinia持久化处理Element Plus(表单校验,表格处理,组件封装)pnpm 包管理升级Eslint prettier 更规范的配置husky(Git hooks工具):代码提交之前,进行校验请求模…

【408真题】2009-24

“接”是针对题目进行必要的分析,比较简略; “化”是对题目中所涉及到的知识点进行详细解释; “发”是对此题型的解题套路总结,并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材(2025版&…

每天学点小知识:图床搭建 + CDN简介

前言: 本章内容帮你解决,本地图片不能分享到网上的问题。需要工具github JSDelivr 知识点 Q:什么是JSDelivr? JSDelivr是一个免费且公开的内容分发网络(CDN),专门用于加速开源项目和静态网站…