【JavaWeb】Day32.SpringBootWeb请求响应——分层解耦(二)

3.IOC&DI

3.1 IOC&DI入门

完成Controller层、Service层、Dao层的代码解耦

思路:

  1. 删除Controller层、Service层中new对象的代码

  2. Service层及Dao层的实现类,交给IOC容器管理

  3. 为Controller及Service注入运行时依赖的对象

  •  Controller程序中注入依赖的Service层对象
  •  Service程序中注入依赖的Dao层对象

第1步:删除Controller层、Service层中new对象的代码

 第2步:Service层及Dao层的实现类,交给IOC容器管理

使用Spring提供的注解:@Component ,就可以实现类交给IOC容器管理

第3步:为Controller及Service注入运行时依赖的对象

使用Spring提供的注解:@Autowired ,就可以实现程序运行时IOC容器自动注入需要的依赖对象

完整的三层代码:

 **Controller层:**

~~~java
@RestController
public class EmpController {

    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpService empService ;

    @RequestMapping("/listEmp")
    public Result list(){
        //1. 调用service, 获取数据
        List<Emp> empList = empService.listEmp();

        //3. 响应数据
        return Result.success(empList);
    }
}
~~~

- **Service层:**

~~~java
@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpServiceA implements EmpService {

    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpDao empDao ;

    @Override
    public List<Emp> listEmp() {
        //1. 调用dao, 获取数据
        List<Emp> empList = empDao.listEmp();

        //2. 对数据进行转换处理 - gender, job
        empList.stream().forEach(emp -> {
            //处理 gender 1: 男, 2: 女
            String gender = emp.getGender();
            if("1".equals(gender)){
                emp.setGender("男");
            }else if("2".equals(gender)){
                emp.setGender("女");
            }

            //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}
~~~

**Dao层:**

~~~java
@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1. 加载并解析emp.xml
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}
~~~

3.2 IOC详解

3.2.1 bean的声明

        IOC控制反转,就是将对象的控制权交给Spring的IOC容器,由IOC容器创建及管理对象。IOC容器创建的对象称为bean对象。在之前的入门案例中,要把某个对象交给IOC容器管理,需要在类上添加一个注解:@Component

        而Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了@Component的衍生注解:

查看源码: 

在IOC容器中,每一个Bean都有一个属于自己的名字,可以通过注解的value属性指定bean的名字。如果没有指定,默认为类名首字母小写。

注意事项:

       声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。

       使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。

3.2.2 组件扫描

使用四大注解声明的bean,要想生效,还需要被组件扫描注解@ComponentScan扫描。

@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了引导类声明注解 @SpringBootApplication 中,默认扫描的范围是SpringBoot启动类所在包及其子包。

解决方案:手动添加@ComponentScan注解,指定要扫描的包   (仅做了解,不推荐)

推荐做法:

- 将我们定义的controller,service,dao这些包呢,都放在引导类所在包com.itheima的子包下,这样我们定义的bean就会被自动的扫描到

3.3 DI详解

依赖注入,是指IOC容器要为应用程序去提供运行时所依赖的资源,而资源指的就是对象。

在入门程序案例中,我们使用了@Autowired这个注解,完成了依赖注入的操作,而这个Autowired翻译过来叫:自动装配。

@Autowired注解,默认是按照类型进行自动装配的(去IOC容器中找某个类型的对象,然后完成注入操作)

例如:  在EmpController运行的时候,就要到IOC容器当中去查找EmpService这个类型的对象,而我们的IOC容器中刚好有一个EmpService这个类型的对象,所以就找到了这个类型的对象完成注入操作。

那如果在IOC容器中,存在多个相同类型的bean对象,程序运行会报错

为了解决上述问题,Spring提供了以下几种解决方案:

  • @Primary
  • @Qualifier
  • @Resource

使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

使用@Qualifier注解:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。@Qualifier注解不能单独使用,必须配合@Autowired使用。

使用@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

补充: @Autowird 与 @Resource的区别

@Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

@Autowired 默认是按照类型注入,而@Resource是按照名称注入

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

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

相关文章

经典机器学习模型(九)EM算法在高斯混合模型中的应用

经典机器学习模型(九)EM算法在高斯混合模型中的应用 EM算法的推导可以参考&#xff1a; 经典机器学习模型(九)EM算法的推导 若随机变量X服从一个数学期望为 μ μ μ、方差为 σ 2 σ^2 σ2的正态分布&#xff0c;可以记为 N ( μ &#xff0c; σ 2 ) N(μ&#xff0c;σ2)…

cmake学习笔记1

基础概念 CMake是什么&#xff1f; CMake是一个元构建系统(meta build-system),用于生产其他构建系统文件&#xff08;如Makefile或Ninja&#xff09;。 基础操作方式 CMake使用一个CMakeLists.txt文件描述配置&#xff0c;然后使用cmake驱动这个文件生成对应构建系统文件。…

【数据结构】ArrayList详解

目录 前言 1. 线性表 2. 顺序表 3. ArrayList的介绍和使用 3.1 语法格式 3.2 添加元素 3.3 删除元素 3.4 截取部分arrayList 3.5 其他方法 4. ArrayList的遍历 5.ArrayList的扩容机制 6. ArrayList的优缺点 结语 前言 在集合框架中&#xff0c;ArrayList就是一个…

【Linux】环境基础开发工具使用——vim使用

Linux 软件包管理器 yum 什么是软件包 1.在 Linux 下安装软件 , 一个通常的办法是下载到程序的源代码 , 并进行编译 , 得到可执行程序 . 2.但是这样太麻烦了 , 于是有些人把一些常用的软件提前编译好 , 做成软件包 ( 可以理解成 windows 上的安装程序) 放在一个服务器…

C#,简单,精巧,实用的文件夹时间整理工具FolderTime

点击下载本文软件&#xff08;5积分&#xff09;&#xff1a; https://download.csdn.net/download/beijinghorn/89071073https://download.csdn.net/download/beijinghorn/89071073 百度网盘&#xff08;不需积分&#xff09;&#xff1a; https://pan.baidu.com/s/1FwCsSz…

ThreadLocal上传下载文件

文章目录 ThreadLocal1.基本介绍1.什么是ThreadLocal&#xff1f;2.示意图 2.快速入门1.创建普通java项目2.编写代码1.T1.java2.T1Service.java3.T2Dao.java4.Dog.java 3.结果 3.ThreadLocal源码解读1.set方法2.set方法总结3.get方法 上传下载文件1.基本介绍1.基本说明2.文件上…

Spring Cloud介绍

一、SpringCloud总体概述 Cloud Foundry Service Broker&#xff1a;通用service集成进入Cloud Foundry Cluster&#xff1a;服务集群 Consul&#xff1a;注册中心 Security&#xff1a;安全认证 Stream&#xff1a;消息队列 Stream App Starters&#xff1a;Spring Cloud Stre…

Redis 客户端

Redis 客户端 客户端-服务器结构 Redis 同 Mysql 一样&#xff0c;也是一个客户端-服务器结构的程序&#xff0c;结构如下图&#xff1a; 注&#xff1a;Redis 客户端和服务器可以在同一个主机上&#xff0c;也可以在不同主机上 Redis 客户端的多种形态 自带的命令行客户端&…

【Qt 学习笔记】详解Qt中的信号和槽

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 详解Qt中的信号与槽 文章编号&#xff1a;Qt 学习笔记 / 12 文章目录…

【Node.js】短链接

原文链接&#xff1a;Nodejs 第六十二章&#xff08;短链接&#xff09; - 掘金 (juejin.cn) 短链接是一种缩短长网址的方法&#xff0c;将原始的长网址转换为更短的形式。短链接的主要用途之一是在社交媒体平台进行链接分享。由于这些平台对字符数量有限制&#xff0c;长网址可…

旋转花键有哪些优缺点?

旋转花键是在花键外筒的外径上装上专用的轴承外套&#xff0c;使之运转动作&#xff0c;适用于水平多关节机械手臂&#xff08;SCARA&#xff09;、产业用机器人、自动装载机、镭射加工机、搬送装置、机械加工中心的ATC装置等各项设备。 目前&#xff0c;旋转花键的应用越来越普…

redis 哨兵

文章目录 前言主从复制的问题怎么人工恢复故障主节点 Redis Setinel 架构使用 docker 来配置哨兵结构安装 docker编排 redis 主从节点编排 redis 哨兵节点 观察哨兵模式的作用主从切换的具体流程小结 前言 redis 主从复制模式下, 一旦主节点出现故障, 不能提供服务的时候, 就需…

刷题之Leetcode283题(超级详细)

283.移动零 283. 移动零https://leetcode.cn/problems/move-zeroes/ 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nu…

第十讲 Query Execution Part 1

1 处理模型【Processing Model】 DBMS 的处理模型【Processing Model】定义了系统如何执行【execute】查询计划【Query Plan】。 针对不同的工作负载进行不同的权衡。 方法1&#xff1a;迭代器模型【Iterator Model】 方法2&#xff1a;物化模型【Materialization Model】 方…

创建和启动线程

概述 Java语言的JVM允许程序运行多个线程&#xff0c;使用java.lang.Thread类代表线程&#xff0c;所有的线程对象都必须是Thread类或其子类的实例。 Thread类的特性 每个线程都是通过某个特定Thread对象的run()方法来完成操作的&#xff0c;因此把run()方法体称为线程执行体。…

数据结构之堆底层实现的循序渐进

题外话 把没写的都补回来! 正题 堆 概念 堆是一棵完全二叉树&#xff0c;因此可以层序的规则采用顺序的方式来高效存储&#xff0c; 大根堆:指根结点比左右孩子都大的堆 小根堆:指根结点比左右孩子都小的堆 性质 1.堆中某个节点的值总是不大于或不小于其父节点的值 2…

CCIE-14-MPLS_and_BGP

目录 实验条件网络拓朴 环境配置开始配置配置MPLSR1访问R6检测结果R6访问R1检测结果 实验条件 网络拓朴 环境配置 在我的资源里可以下载&#xff08;就在这篇文章的开头也可以下载&#xff09; 开始配置 R1<->R2&#xff1a;EBGP R2<->R5&#xff1a;IBGP&…

蓝桥杯备考3

P8196 [传智杯 #4 决赛] 三元组 题目描述 给定一个长度为 n 的数列 a&#xff0c;对于一个有序整数三元组 (i,j,k)&#xff0c;若其满足 1≤i≤j≤k≤n 并且&#xff0c;则我们称这个三元组是「传智的」。 现在请你计算&#xff0c;有多少有序整数三元组是传智的。 输入格式…

小米手机澎湃OS,不Root查看电池健康

首先&#xff0c;在键盘拨号界面&#xff0c;输入*#*#284#*#*&#xff0c;会调用问题反馈APP来生成当前系统的故障日志&#xff0c;如果提示你需要授权什么就点确认 稍等几分钟&#xff0c;会得到一个压缩包&#xff0c;保存在目录MIUI/debug_log下 这里为了方便&#xff0c;我…

肖恩带你学C语言·文件操作(上)

1. 为什么使用文件 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运行程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进行持久化的保存&…