Spring中@Autowired注解用法详解

2023-10-27

1.概述

Spring中IOC可以通过注解方式实现,只要在spring的配置文件applicationContext.xml中配置开启了包扫描Spring会自动扫描指定包及其子孙包。

<!-- 开启包扫描 -->
<context:component-scan base-package="cn.tedu.beans"/>

在类上添加注解@Component则实现了通过注解注册bean,此时这个类就被spring管理了。具体过程可以描述为:

当Spring容器解析到@Component注解时,创建当前类的bean在spring容器中进行管理,在创建bean的过程中发现了@Autowired注解,会根据当前bean类型,寻找在spring中是否存在该类型的bean,找到直接注入,如果找不到还会检查是否有子孙类、实现类存在,如果存在唯一的则自动注入,如果还是没有找到或找到多个无法注入,则还会按照属性名对应id去查找对应的bean,如果存在则注入,如果还是没有找到则抛出异常。也可以额外配置@Qualifier(value="dog1")注解强制要求按照id寻找bean,则此时会直接使用给定的id寻找bean,而不会进行基于类型的匹配。

@Autowired:

  • 在bean中的属性上通过@Autowired实现自定义bean类型的属性注入
  • 使用是对应的bean必须被spring管理,即手动配置了bean或者在类上添加了@Component注解

DI:就是注入功能,通俗的说就是给IOC创建出来的对象属性赋值

2.只有@Autowired,没有@Qualifier情况

先按照类型匹配,即按照当前bean类型寻找是否存在指定类型的bean
如果找到唯一的bean直接注入
如果找不到或找到多个则开始按照id注入(默认取当前属性名)
找到唯一的则注入,找不到则抛出异常,不可能找到多个。

具体的通过如下代码描述:

如下有一个英雄类hero他有一个属性,可以带一只狗,提供了狗类Dog,提供了狗类的子类金毛狗JMDog,哈士奇狗HSQDog

类结构如下:

情况一:在英雄类中只添加了@Autowired注解,且只将Dog类交给Spring容器管理,那么按照顺序应该是先按照类型匹配,当前给出的是Dog类

经过测试@Autowired注解按照类型就找到了唯一的bean--Dog类于是注入该类

情况二:将Dog的子类JMDog,HSQDog 也加入spring容器管理,此时按照类型去找就会找到多个,因为JMDog,HSQDog都是Dog类,此时按照id去找

id为dog所以找到的就是Dog类,然后注入

 如果将对象名改为hsqdog,此时会抛出异常,原因是因为注解的推断规则

(推断规则请查阅文章:https://blog.csdn.net/qq_32224047/article/details/107005905

根据推断规则,如果要找哈士奇类,给的id名应该是HSQDog,验证成功,完全符合注解的推断规则

 如果一定要用hsqdog那么只需要在HSQDog类上指定id就行

测试根据hsqdog 这个id能找到 HSQDog类

情况三,如果根据类型和id 都找不到就会抛出异常,如给一个不存在的京巴狗,JBDog,那么就不会找到,抛出异常

 

3.@Autowired和@Qualifier一起使用

  •  此注解可以配合@Autowired使用
  •  一旦同时配置@Autowired和@Qualifier,则不再按照类型去匹配,直接按照id匹配
  • 如果按照id能找到就注入,找不到就抛出异常
  • 此注解可以指定要使用的id,如果不指定默认是空串,会抛出异常

情况一:在@Qualifier上指定id,那么找到的就是该id的bean,找不到抛出异常,如下指定id为JMDog,找到的就是JMDog

情况二:当不指定id时,默认会给一个空串,所以空串是不会找到的,使用@Qualifier必须指定一个id

查看注解源码,默认给的就是空串

因为是空串,找不到就抛出异常 

 

在软件分层时,一般都会定义一个接口就对应的实现类,然后将实现类交给Spring容器管理,当在其他层需要使用时通过@Autowired注入

代码如下:

在service层定义了接口及实现类,并将实现类交给spring容器管理(采用@Service--具体将类注册为bean需要如何使用正确的注解,可以查阅文章:https://blog.csdn.net/qq_32224047/article/details/107010098

 当控制层调用Service层时,等号左边为接口对象等号左边赋值为null,让spring容器自动注入(这种写法降低了耦合),当@Autowired扫描到时根据自动推断规则,就找到了实现类UserServiceImpl,并注入该实现类的对象,因为这个实现类交给了spring容器管理,因为UserService是接口,接口不会创建对象所以即使将接口交给spring容器管理,找到的还是他对应的实现类。

3.执行流程图

 

4.@Autowired(required=false)

4.1描述:

在使用spring开发过程中,我们基本上都是使用@Autowired这个注解,用来注入已有的bean。但是有些时候,会注入失败。当我们加上参数(required=false)就能解决

4.2required属性:

  • @Autowired(required=true):当使用@Autowired注解的时候,其实默认就是@Autowired(required=true),表示注入的时候,该bean必须存在,否则就会注入失败。
  • @Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。

 4.3使用场景

我们的正常使用会在Controller层注入service,在service中注入mapper。

但是如果有一个公用方法,需要注入某个元素,并且这个方法在公用模块里。当该模块被引入其他项目中,该项目中并需要注入所需的bean时,就出现错误。那么问题来了,我们项目中并不需要该要注入的类,使得整个项目报错

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring中@Autowired注解用法详解 的相关文章

随机推荐

  • (ESP32学习7)双核使用队列进行任务间通信

    这里是调用双核的方法哈 和我们单核使用的方法不兼容 因为有一些函数是不一样的 不通用 但是下一篇博文我会更一篇单核使用队列进行任务间通讯的问题 队列是什么 队列是可以从一个任务向其他任务以并发安全的方式发送消息的机制 也就是说他的目标是实现
  • C语言各变量类型占字节数

    C语言变量所占字节数整理 变量的基本类型包括 字符型 整型 长整型 浮点型 每个变量在每个编译器所占的字节数不同 the C Programming language 是这样说的 Each compiler is free to choos
  • c++11新特性实战:智能指针

    c 11添加了新的智能指针 unique ptr shared ptr和weak ptr 同时也将auto ptr置为废弃 deprecated 但是在实际的使用过程中 很多人都会有这样的问题 不知道三种智能指针的具体使用场景 无脑只使用s
  • 【kali换源后报错:The repository ‘http://old.kali.org/kali moto InRelease‘ is not signed.的解决办法】

    问题描述 添加旧源 vim etc apt sources list 末行追加 deb http old kali org kali moto main non free contrib 更新源 apt get update 报错 Err
  • python,Pycharm导入自定义包

    1 Pycharm中如何让导入的自定义包生效 第一步 File gt Settsing gt Build Executions Deployment gt Console gt Python Console gt 勾选 add source
  • Android——使用Spinner实现下拉列表

    1 执行步骤 1 确定数据源 添加一个下拉列表项的list 2 定义适配器 添加数据源 为下拉列表定义一个数组适配器ArrayAdapter 3 为适配器设置下拉时的菜单样式 adapter setDropDownViewResource
  • 【Python项目】简易的密码本

    import json 名称文件 名称 json 账号文件 账号 json 密码文件 密码 json 名称 账号 密码 序列号 0 更新数据 with open 账号文件 as f 账号 json load f with open 名称文件
  • js代替eval的办法

    在滚滚的boring写代码的潮流中 eval 方法逐渐被淘汰 那我们可以用什么方法代替它呢 binggo 以下方法使用效果超出你的想象 function evalPro str var Fn Function return new Fn r
  • layui框架学习(5:面板)

    Layui中的菜单样式与面板结合比较紧密 在学习菜单之前 先熟悉Layui的面板样式 Layui的面板主要作为容器使用 其样式主要分为常规面板 卡片面板 折叠面板 含手风琴效果 Layui官网示例中还介绍了面板嵌套 本文后续一一介绍并验证
  • 图像描述算法排位赛:SceneXplain与MiniGPT-4谁将夺得桂冠?

    如果你对 AI 前沿感兴趣 本场 图像描述算法排位赛 绝对是你不能错过的 在这场较量中 SceneXplain 和 MiniGPT 4 将会比试 谁将摘得这场比赛的桂冠 直接上手体验 scenex jina ai 背景介绍 在 一张图就是一
  • php curl集成包的安装和实用

    下载curl集成包 https github com php mod curl 放在vendor目录下 加载curl包 实例化 vendor Curl src Curl Curl php pinJ new Curl 然后按照官网demo使用
  • 图像配准的方法

    转自 http blog sina com cn s blog 4b9b714a0100d5k5 html 图像配准的方法 1 基于特征的图像配准 基于特征的图像配准首先提取图像信息的特征 然后以这些特征为模型进行配准 特征提取的结果是一含
  • QT的ui文件中控件在cpp的调用

    点击然后右键 然后点击改变对象名称 改成如上图所示 即可在cpp函数中调用 进行操作
  • cdn搭建原理_什么叫cdn服务器?怎么部署?

    在现今的网络系统时期 各类互连网手机app异军突起 而互联网出現浏览卡屏或延时的状况也越来越非常广泛 以便处理不一样的互联网情况 人们常常会构建到不一样的虚拟主机来浏览互联网 cdn服务器也是列举这种 什么叫cdn服务器 cdn服务器英语全
  • CentOS7.x安装VNC实录

    不知不觉 centos已经到7 6了 在服务器操作系统中 centos是用的比较多的 占很大的比例 由于7 x版本和6 x版本有区别 最近安装了7 6的VNC 特记之 VNC需要系统安装的有桌面 如果是生产环境服务器 安装时使用的最小化安装
  • 学妹问我:OpenJDK是什么?作为师哥,必须万字详解屁颠屁颠奉上

    上一篇是分享的是 JVM虚拟机 了解Java堆中对象分配 布局和访问的全过程 这篇给大家分享 OpenJDK 1 OpenJDK 概述 OpenJDK 是 Java 平台标准版 Java SE 的免费开源实现 这是 Sun Microsys
  • python爬虫安装Xpath插件时遇到的问题

    在安装Xpath时 出现拖拉压缩包 记住一定是压缩包 下载后的插件是 crx后缀的文件 需要改变为压缩包的形式 后 在添加文件时 一直找不到压缩包 最后发现是压缩包后缀的问题 如图 是我的winr 压缩包软件 自动生成的压缩包 默认是rar
  • 数据聚合与分组运算

    标注 我用的是jupyterNotebook 一 分组与聚合的原理 在Pandas中 分组是指使用特定的条件将原数据划分为多个组 聚合在这里指的是 对每个分组中的数据执行某些操作 最后将计算的结果进行整合 分组与聚合的过程大概分为以下三步
  • nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

    问题描述 这个报错指的是结果无法映射 只需要把java实体与数据库表关系映射好就ok 一定要看清自己的配置文件 自己的数据库 处理思路整理 避免走弯路 1 首先验证是不是代码写出 String sql select count 1 from
  • Spring中@Autowired注解用法详解

    1 概述 Spring中IOC可以通过注解方式实现 只要在spring的配置文件applicationContext xml中配置开启了包扫描Spring会自动扫描指定包及其子孙包