分层解耦-05.IOCDI-DI详解
一.依赖注入的注解
在我们的项目中,EmpService的实现类有两个,分别是EmpServiceA和EmpServiceB。这两个实现类都加上@Service注解。我们运行程序,就会报错。
这是因为我们依赖注入的注解@Autowired默认是按照类型来寻找bean对象的进行依赖注入的,controller程序会在IOC容器中寻找到两个service的bean对象,此时他会不知道使用哪一个,就会上面的报错。
@Autowired // DI:依赖注入,service依赖于dao,运行时IOC容器会提供该类型的bean对象,并赋值给该变量private EmpService empService;
为了解决这个问题,要么就将其中的一个@Service注解去掉,或者采用方法二,使用依赖注入的注解来指定注解的优先级。
二.@Primary注解
@Primary注解作用在bean对象上,当IOC容器中有多个不同实现类的bean对象时,哪个实现类上面加上了@Primary注解,哪个实现类的bean对象就会起作用。
package com.gjw.service.impl;import com.gjw.dao.EmpDao;
import com.gjw.pojo.Emp;
import com.gjw.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;import java.util.List;//@Component // IOC:控制反转,将实现类对象交给容器。将当前类交给IOC容器管理,成为IOC容器中的bean
@Primary
@Service
public class EmpServiceA implements EmpService {@Autowired // DI:依赖注入,service依赖于dao,运行时IOC容器会提供该类型的bean对象,并赋值给该变量private EmpDao empDao;@Overridepublic List<Emp> listEmp() {List<Emp> empList = empDao.listEmp();empList.stream().forEach(emp ->{if ("1".equals(emp.getGender())) {emp.setGender("男");} else if ("2".equals(emp.getGender())) {emp.setGender("女");}if ("1".equals(emp.getJob())) {emp.setJob("讲师");} else if ("2".equals(emp.getJob())) {emp.setJob("班主任");} else if ("3".equals(emp.getJob())) {emp.setJob("就业指导");}});return empList;}
}
三.@Qualifier注解
@Qualifier注解主要是配合着@Autowired注解使用,在要注入的类(此处是controller)的@Autowired注解下面加上@Qualifier(bean对象名字)
(bean对象名字)默认是实现类类名首字母小写
package com.gjw.controller;
/*对xml文件进行处理,从而加载处理要响应的数据*/
import com.gjw.pojo.Emp;
import com.gjw.pojo.Result;
import com.gjw.service.EmpService;
import com.gjw.service.impl.EmpServiceA;
import com.gjw.utils.XmlParserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController
public class EmpController {@Autowired // DI:依赖注入,service依赖于dao,运行时IOC容器会提供该类型的bean对象,并赋值给该变量@Qualifier("empServiceB")private EmpService empService;@RequestMapping("/listEmp")public Result list(){List<Emp> empList = empService.listEmp();return Result.success(empList);}
/*@RequestMapping("/listEmp")public Result list(){// 1.加载emp.xml,并解析emp.xml中的数据String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();System.out.println(file);List<Emp> empList = XmlParserUtils.parse(file, Emp.class);// 2.对员工信息中的gender,job字段进行处理empList.stream().forEach(emp ->{if ("1".equals(emp.getGender())) {emp.setGender("男");} else if ("2".equals(emp.getGender())) {emp.setGender("女");}if ("1".equals(emp.getJob())) {emp.setJob("讲师");} else if ("2".equals(emp.getJob())) {emp.setJob("班主任");} else if ("3".equals(emp.getJob())) {emp.setJob("就业指导");}});// 3.组装数据并返回return Result.success(empList);}
*/
}
指定empServiceB这个bean对象生效。
四.@Resouce注解
使用@Resouce注解,@Autowired注解默认是按照bean对象的类型进行选择的。@Resouce注解是按照名称进行bean对象的选择的。@Resouce(bean对象名字)
package com.gjw.controller;
/*对xml文件进行处理,从而加载处理要响应的数据*/
import com.gjw.pojo.Emp;
import com.gjw.pojo.Result;
import com.gjw.service.EmpService;
import com.gjw.service.impl.EmpServiceA;
import com.gjw.utils.XmlParserUtils;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController
public class EmpController {/*@Autowired // DI:依赖注入,service依赖于dao,运行时IOC容器会提供该类型的bean对象,并赋值给该变量@Qualifier("empServiceB")*/@Resource(name = "empServiceB")private EmpService empService;@RequestMapping("/listEmp")public Result list(){List<Emp> empList = empService.listEmp();return Result.success(empList);}
/*@RequestMapping("/listEmp")public Result list(){// 1.加载emp.xml,并解析emp.xml中的数据String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();System.out.println(file);List<Emp> empList = XmlParserUtils.parse(file, Emp.class);// 2.对员工信息中的gender,job字段进行处理empList.stream().forEach(emp ->{if ("1".equals(emp.getGender())) {emp.setGender("男");} else if ("2".equals(emp.getGender())) {emp.setGender("女");}if ("1".equals(emp.getJob())) {emp.setJob("讲师");} else if ("2".equals(emp.getJob())) {emp.setJob("班主任");} else if ("3".equals(emp.getJob())) {emp.setJob("就业指导");}});// 3.组装数据并返回return Result.success(empList);}
*/
}
注意:当我们使用Resouce注解时,是JDK框架提供Resouce注解。而使用Autowired时使用的是springboot框架提供Autowired注解。
五.总结
相关文章:

分层解耦-05.IOCDI-DI详解
一.依赖注入的注解 在我们的项目中,EmpService的实现类有两个,分别是EmpServiceA和EmpServiceB。这两个实现类都加上Service注解。我们运行程序,就会报错。 这是因为我们依赖注入的注解Autowired默认是按照类型来寻找bean对象的进行依赖注入…...

HCIP-HarmonyOS Application Developer 习题(六)
(多选)1、Harmonyos多窗口交互能力提供了以下哪几种交互方式? A. 平行视界 B.全局消息通知 C.分屏 D.悬浮窗 答案:ACD 分析:系统提供了悬浮窗、分屏、平行视界三种多窗口交互,为用户在大屏幕设备上的多任务并行、便捷…...

【电路基础 · 3】实际电压源 实际电流源;两种电源的等效情况;戴维南模型 诺顿模型(自用)
总览 1.实际电源的两种模型和它们的等效变换 2.两种电源的等效情况 3.戴维南模型 && 诺顿模型 一、实际电源的两种模型和它们的等效变换 1.实际电压源 实际电压源不允许短路。因为它的内阻太小,如果短路,电流很大,可能会烧毁电源…...

案例-猜数字游戏
文章目录 效果展示初始画面演示视频 代码区 效果展示 初始画面 演示视频 猜数字游戏 代码区 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,…...

POI数据的处理与分析
POI概念 POI(Point of Interest,兴趣点)数据指的是地理空间数据中的一类,表示某一具体地点或位置的信息。通常,这些数据包含位置坐标(经纬度)、名称、地址、类别和其他相关信息。POI 数据广泛应…...

ansible部分模块学习
ansible模块学习 copy模块 copy模块srcsource 源⽂件destdestination ⽬标backupbackupyes 则会在覆盖前进⾏备份mode修改权限owner修改为指定所有者group修改为指定⽤户组 案例1:传输/root/work/scripts/net-tools-install.sh⽂件到/opt/net-tools-install.sh …...

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(二).设置主键自增等特点
前言 在上一节中,主要介绍了 Navicat Premium 17 的使用以及创建一个基础的表格。当时只设置了给数据表补充字段,没有设置给数据表删除字段。现在补充一下。 ALTER TABLE student ADD test int(4); 给名为 student 的数据表添加 test 列…...

SQL第13课——创建高级联结
本课讲另外一些联结(含义和使用方法),如何使用表别名,如何对被联结的表使用聚集函数。 13.1 使用表别名 第7课中使用别名引用被检索的表列,给列起别名的语法如下: SQL除了可以对列名和计算字段使用别名&a…...

订阅ROS2中相机的相关话题并保存RGB、深度和点云图
系统:Ubuntu22.04 ROS2版本:ROS2 humble 1.订阅ROS2中相机的相关话题并保存RGB图、深度图和点云图 ros2 topic list/stellar_1/rgb/image_raw /camera/depth/image_raw /stellar_1/points2CMakeLists.txt cmake_minimum_required(VERSION 3.15) projec…...

Open WebUI | 自托管的类 ChatGPT 网站
Open WebUI 是一个扩展性强、功能丰富且用户友好的自托管 WebUI,旨在完全离线操作。它支持各种 LLM 服务,包括 Ollama 和 OpenAI 兼容的 API。该项目在 GitHub 上已有 38k 星,非常受欢迎。 功能介绍 废话不多说,上图!…...

【Python】Python知识总结浅析
Python是一种高级编程语言,由Guido van Rossum于1991年首次发布。它以简洁的语法和强大的功能著称,适用于多种应用场景,包括Web开发、数据分析、人工智能、自动化脚本等。 易于学习和使用:Python的语法简洁明了,适合初…...

c#代码介绍23种设计模式_20策略者模式
目录 1、策略模式的定义 2、策略模式的结构 3、涉及到三个角色: 4、策略者模式在.NET中应用 5、策略者模式的适用场景 6、策略者模式的优缺点 7、实现思路 在现实生活中,策略模式的例子也非常常见,例如,中国的所得税,分为企业所得税、外商投资企业或外商企业所得税…...

FPGA-UART串口接收模块的理解
UART串口接收模块 背景 在之前就有写过关于串口模块的文章——《串口RS232的学习》。工作后很多项目都会用到串口模块,又来重新理解一下FPGA串口接收的代码思路。 关于串口相关的参数,以及在文章《串口RS232的学习》中已有详细的描述,这里就…...

复习HTML(基础)
目录 HTML含义 HTML作用 HTML的常用元素 元素的特点 元素的分类 1 是否嵌套关系 2 是否独占一行 块元素:独占一行 行内元素:共享一行 行内元素与块级元素的转换 3是否有结束标签 常用标签 1 标题标签:有六级 我们用h1 ~h6 表…...

Linux聊天集群开发之环境准备
一.windows下远程操作Linux 第一步:在Linux终端下配置openssh,输入netstate -tanp,查看ssh服务是否启动,默认端口22.。 注:如果openssh服务,则需下载。输入命令ps -e|grep ssh, 查看如否配有, ssh-agent …...

can 总线入门———can简介硬件电路
文章目录 0. 前言1. CAN简介2. 主流通讯协议对比3. CAN 硬件电路4. CAN 电平标准5. CAN 收发器 0. 前言 博客内容来自B站上CAN总线入门教程视频讲解,博客中的插图和内容均为视频中的内容。视频链接 CAN总线入门教程 1. CAN简介 先来看看一它名字的意思,…...

【重学 MySQL】六十、空间类型
【重学 MySQL】六十、空间类型 空间数据类型的分类空间数据类型的属性空间数据的表示方式空间数据的操作应用场景 在MySQL中,空间类型(Spatial Types)主要用于支持地理特征的生成、存储和分析。这些地理特征可以表示世界上具有位置的任何东西…...

python实现DES算法
DES算法 一、算法介绍1.1 背景1.2 原理1.3 基本功能函数1.3.1 初始置换函数 I P IP IP1.3.2 f f f 轮函数1.3.3 逆初始置换函数 I P − 1 IP^{-1} IP−1 1.4 子密钥的生成 二、代码实现2.1 子密钥生成实现2.2 DES加解密实现2.3 完整代码 三、演示效果 一、算法介绍 1.1 背景…...

基于LORA的一主多从监测系统_框架搭建
第一节、框架搭建 打开CubeMAX,选择好芯片,进行基础配置 第一步、先配置时钟源 第二步、配置SYS选项 配置debug口以及计数器源,我这里选择TIM1 第三步、选择I2C接口 配置如下即可,默认配置不用改 第四步、串口选择 我们这里使…...

优化理论及应用精解【25】
文章目录 优化学习率调度1. 阶梯衰减(Step Decay)2. 余弦退火(Cosine Annealing)3. 多项式衰减(Polynomial Decay)4. 指数衰减(Exponential Decay)总结 梯度弥散效应 参考文献 优化 …...

贝锐蒲公英网盘首发,秒建私有云,高速远程访问
虽然公共网盘带来了不少便利,但是大家对隐私泄露和重要数据泄密的担忧也随之增加。如果想要确保数据安全,自建私有云似乎是一条出路,然而面对搭建私有云的复杂步骤,许多人感到力不从心,NAS设备的成本也往往让人望而却步…...

[ 蓝桥 ·算法双周赛 ] 第 19 场 小白入门赛
🔥博客介绍: EvLast 🎥系列专栏: <<数据结构与算法>> << 算法入门>> << C项目>> 🎥 当前专栏: << 算法入门>> 专题 : 帮助小白快速入门算法竞赛 👍…...

HTML+CSS基础 第二季课堂笔记
一、列表 列表都不是单打独斗的,通常都是一组标签组成 1 无序列表 作用:定义一个没有顺序的列表结构 由两个标签组成,ul(容器级标签),li(容器级) ul:英文ulordered …...

【Easy RL】Easy RL蘑菇书全书学习笔记
【Easy RL】Easy RL蘑菇书全书学习笔记 第一章 强化学习基础1.1 强化学习概述监督学习强化学习与监督学习的不同之处二者的区别总结强化学习的特征强化学习的优越性预演(rollout)和 轨迹(trajectory)的概念端到端的概念深度强化学…...

JavaWeb(二)
Servlet开发技术 [外链图片转存中…(img-Cnu8X2V4-1728026684827)] 简述Servlet的创建过程? package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; …...

【C++】--类和对象(2)
👌个人主页: 起名字真南 👆个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 类的默认成员函数2 构造函数3 析构函数4 拷贝构造5 赋值运算符重载5.1 运算符重载5.2 赋值运算符的重载 1 类的默认成员函数 默认成员函数就是用户没有显示实现,…...

最新BurpSuite2024.9专业中英文开箱即用版下载
1、工具介绍 本版本更新介绍 此版本对 Burp Intruder 进行了重大改进,包括自定义 Bambda HTTP 匹配和替换规则以及对扫描 SOAP 端点的支持。我们还进行了其他改进和错误修复。 Burp Intruder 的精简布局我们对 Burp Intruder 进行了重大升级。现在,您可…...

C++ 观察者模式
观察者模式(Observer Pattern)是一种行为设计模式,用于在对象之间建立一对多的依赖关系,当一个对象的状态发生变化时,它的所有依赖对象都会得到通知并自动更新。 在观察者模式中,主题和观察者之间是松耦合…...

基于pytorch的手写数字识别-训练+使用
import pandas as pd import numpy as np import torch import matplotlib import matplotlib.pyplot as plt from torch.utils.data import TensorDataset, DataLoadermatplotlib.use(tkAgg)# 设置图形配置 config {"font.family": serif,"mathtext.fontset&q…...

SpringBoot接收前端传递参数
1)URL 参数 参数直接 拼接在URL的后面,使用 ? 进行分隔,多个参数之间用 & 符号分隔。例如:http://localhost:8080/user?namezhangsan&id1后端接收(在Controller方法的参数列表中使用 RequestParam 注解&…...