Javaweb学习记录(四)分层处理架构-分层解耦

三层架构

程序设计分为下面三层架构,分别为Controller控制层,Service逻辑处理层,Dao数据访问层。这三层各自执行自己所对应的功能,使程序的扩展性和可维护性提高

例如下面我想设计一个分层的程序,实现Controller层,Service层,Dao层。

需求:

1、将本地xml文件中的数据解析,且用其属性值创建相应对象,将对象放入集合中(Dao层)

2、将集合中的对象的部分属性值进行修改,将修改后的集合进行返回(逻辑处理Service层)

3、将处理好的集合使用Result类进行规范返回响应前端的请求(Controller层)

本程序则需要先在Dao层中创建相关接口,再用相关接口实现类实现该接口,并得到相应的对象集合数据,再在Service层中创建相关接口,创建相关接口实现类,在该类中创建Dao层实现类对象,通过调用类里的方法,得到Dao层返回的集合,在Service实现类对象中对该集合进行处理,并返回该集合,最后在Controller层中创建Service层的实现类对象,通过调用里面的方法得到经过数据处理了的集合,再将该集合用Result规范响应前端的请求。具体分布图如下:

Dao层代码:(不包括接口)

package com.itazhang.dao.impl;import com.itazhang.dao.EmpDao;
import com.itazhang.pojo.Emp;
import com.itazhang.utils.XmlParserUtils;import java.util.List;public class EmpDaoA implements EmpDao {@Overridepublic List<Emp> listEmp() {//编码并解析emp.xml文件String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();List<Emp> emplist = XmlParserUtils.parse(file, Emp.class);return emplist;}
}

Service层代码(不包括接口)

package com.itazhang.service.impl;import com.itazhang.dao.EmpDao;
import com.itazhang.dao.impl.EmpDaoA;
import com.itazhang.pojo.Emp;
import com.itazhang.service.EmpService;import java.util.List;public class EmpServiceA implements EmpService {private EmpDao empDao = new EmpDaoA();//创建Dao层的实例化对象@Overridepublic List<Emp> empService() {List<Emp> emplist = empDao.listEmp();//通过实例化对象获取到Dao层数据处理之后的返回值emplist.stream().forEach(emp -> {//处理性别返回String gender = emp.getGender();if("1".equals(gender)){emp.setGender("男");}else{emp.setGender("女");}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;}
}

Controller层代码

package com.itazhang.controller;import com.itazhang.dao.impl.EmpDaoA;
import com.itazhang.pojo.Emp;
import com.itazhang.pojo.Result;
import com.itazhang.service.EmpService;
import com.itazhang.service.impl.EmpServiceA;
import com.itazhang.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class EmpController {//创建Service层接口实例化对象private EmpService emps = new EmpServiceA();@RequestMapping("/listEmp")public Result list(){List<Emp> emplist = emps.empService();//响应数据return Result.success(emplist);}
}

分层解耦思想:

如果一个程序的不同层之间出现耦合,也就是例如在上例中Service层如果要进行数据的逻辑处理的话必须new一个Dao层的对象,通过调用该对象的方法来获取到需要进行逻辑处理的数据,这样程序之间存在的一定联系就是耦合,这种情况会存在许多缺点,例如如果我想要在Service层中去修改需要处理的数据对象,那么必须修改创建的Dao层的对象从而获取到新的数据。这时候分层解耦思想就能被很好的应用,将所有的对象创建都交给外部的容器而不是各个层,如果哪个层需要其他层的对象来实现相关功能,直接由容器创建并把该对象交给他,这样的话就是每层与容器关联而不是层与层互相关联,这时只要每层想要修改本层所使用的数据,只需要重新从容器中获取相应层的对象调用方法就行,而不用在本层中去修改相应层创建的对象。

IOC 控制反转与DI依赖注入的实现

在实际开发中,因为可以快速区分Service层Dao层和Controller层,所以一般使用

Service层对应的@Service注解,Controller层使用的@Controller注解,Dao层对应的@Repository注解来替代@Component注解,@Component注解一般是一些不属于这些层但也需要被IOC容器管理的类进行使用。

在springboot项目中主要通过@Component注解实现控制反转,使用@Autowired实现依赖注入,将需要交给容器管理的类用@Component注解标记表示将该类的创建交给容器管理,再到需要创建该类的其他类里只写创建接口实例化对象但不具体表面创建哪个实例化的对象,并将该创建语句前加上@Autowired注解,这样容器就会根据前面创建接口实例化对象的语句自动分配需要创建的bean对象,例如上例

Service层需要Dao层的数据:那么就将Dao层加上@Component注解,将Dao层的创建交给容器管理,Dao层代码实现如下:

package com.itazhang.dao.impl;import com.itazhang.dao.EmpDao;
import com.itazhang.pojo.Emp;
import com.itazhang.utils.XmlParserUtils;
import org.springframework.stereotype.Component;import java.util.List;
@Component
public class EmpDaoA implements EmpDao {@Overridepublic List<Emp> listEmp() {//编码并解析emp.xml文件String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();List<Emp> emplist = XmlParserUtils.parse(file, Emp.class);return emplist;}
}

Service层需要创建Dao层的实例化对象,而Controller层也需要创建Servicer层的对象,那么就将Service层的实例化类加上@Component注解,表示将Service层的类创建权交给容器。给Service层实例类里创建的Dao层对象加上@Autowired注解,表示创建Dao层接口的实例化对象时,容器自动注入相关的bean对象,具体代码实现如下:

package com.itazhang.service.impl;import com.itazhang.dao.EmpDao;
import com.itazhang.dao.impl.EmpDaoA;
import com.itazhang.pojo.Emp;
import com.itazhang.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.List;
@Component
public class EmpServiceA implements EmpService {@Autowiredprivate EmpDao empDao ;//创建Dao层的实例化对象@Overridepublic List<Emp> empService() {List<Emp> emplist = empDao.listEmp();//通过实例化对象获取到Dao层数据处理之后的返回值emplist.stream().forEach(emp -> {//处理性别返回String gender = emp.getGender();if("1".equals(gender)){emp.setGender("男");}else{emp.setGender("女");}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;}
}

Controller层则是需要实现接收和响应前端发送来的请求所以需要在类上添加@RestController注解,使该类实现对前端的接收请求和响应功能,而响应的数据来源于Service层,所以创建Service接口的实例化对象的代码前需要添加@AutoWired注解,表示需要创建Service层的实现类的时候将自动注入bean对象,具体代码实现如下 :

package com.itazhang.controller;import com.itazhang.pojo.Emp;
import com.itazhang.pojo.Result;
import com.itazhang.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class EmpController {//创建Service层接口实例化对象@Autowiredprivate EmpService emps;@RequestMapping("/listEmp")public Result list(){List<Emp> emplist = emps.empService();//响应数据return Result.success(emplist);}
}

而这就会实现减少层之间的耦合性,例如之前的Service层实现类是ServiceDemo1,我要求新添加一种数据逻辑也就是新创建了一个Service层的实现类ServiceDemo2,我需要将该实现类的逻辑添加到项目中,我只需要删除之前的ServiceDemo1的@Component注解,在现在的ServiceDemo2上添加@Component注解,相当于将现在的Service层实现类的对象创建交给IOC容器管理,这样的话,后面创建的Service层的实例化对象就会是ServiceDemo2的对象,我要将Service层数据处理逻辑改变的需求就得以实现。

如果同类型的bean出现多个那么用以下注解进行解决

@Resource注解是通过bean的名称注解,相当于在注解时我们手动的为他表示需要注入哪个名称的bean,而@Autowired就是自动注解

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

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

相关文章

MidJourney 使用指北

官网&#xff1a;docs.midjourney.com 文档&#xff1a;docs.midjourney.com/docs/quick-… PS&#xff1a;魔法需要订阅使用了 准备工作 一、进入 discord官网 二、下载 Discord App 三、注册Discord账号 创建服务器 登录 discord App&#xff0c;点击添加按钮&#xff…

AJAX——综合案例

1 Bootstrap弹框 功能&#xff1a;不离开当前页面&#xff0c;显示单独内容&#xff0c;供用户操作 步骤&#xff1a; 引入bootstrap.css和bootstrap.js准备弹框标签&#xff0c;确认结构通过自定义属性&#xff0c;控制弹框的显示和隐藏 <!DOCTYPE html> <html la…

详解Java常用排序算法(10种,含演示动画)

Java常用的排序算法有以下几种&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;选择排序&#xff08;Selection Sort&#xff09;插入排序&#xff08;Insertion Sort&#xff09;希尔排序&#xff08;Shell Sort&#xff09;归并排序&#xff08;Merge Sort&#x…

Android Studio:你的主机中的软件终止了一个已建立的连接

我不喜欢等人也不喜欢被别人等——赤砂之蝎 一、提出问题 二、分析问题 搜索网上的教程尝试解决 1、任务管理器结束adb进程无用 2、电脑没有开启热点排除热点问题 3、校园网切换到热点 4、项目重新解压打开 5、更换国内镜像源 上述方法全部无法解决问题 分析问题原因在于之前A…

Github 2024-03-18 开源项目周报Top15

根据Github Trendings的统计,本周(2024-03-18统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目6TypeScript项目2Go项目2JavaScript项目2非开发语言项目1HTML项目1CSS项目1Rust项目1Dart项目1C++项目1Jupyter Notebook项目1Electr…

JVM中对象创建过程

在JVM中对象的创建&#xff0c;我们从一个new指令开始&#xff1a; 这个过程大概图示如下&#xff1a; 虚拟机收到new指令触发。 类加载检查&#xff1a;如果类没有被类加载器加载&#xff0c;则执行类加载流程&#xff08;将class信息加载到JVM的运行时数据区的过程&#xff…

Stable Diffusion + Segment Anything试用

安装 从continue-revolution/sd-webui-segment-anything安装插件分割模型下载后放到这个位置&#xff1a;${sd-webui}/extension/sd-webui-segment-anything/models/sam下&#xff0c;可以下载3个不同大小的模型&#xff0c;从大到小如下&#xff1a;vit_h is 2.56GB, vit_l i…

Java后端八股----JVM篇

上图中线程1&#xff0c;2如果资源被抢占了&#xff0c;则程序计数器记录一下执行的行号&#xff0c;等到资源就绪后会从记录的行号继续向后执行。 Java8把静态变量以及常量放到了线程的本地内存原空间中(避免放在堆中不可控)。 &#x1f446;图中第二种情况不太容易出现…

Linux docker2--镜像及容器操作-nginx部署示例

一、上一篇已经完成了docker的基础环境搭建&#xff0c;和docker的安装。不清楚的小伙伴可以自己找上一篇看一下。本例以部署nginx为例展示 二、镜像相关 1、切换docker的镜像源为阿里云 命令&#xff1a; sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <&l…

敏捷开发——elementUI/Vue使用/服务器部署

1. 创建vue项目 2. 安装element-ui组件库 npm i -S element-ui或 npm install element-ui3. 在main.js中导入element-ui组件 import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css Vue.use(ElementUI)4. 运行 npm run serve后可以使用 ctrc终止进…

如何选择合适的数据可视化工具?

如果是入门级的数据可视化工具&#xff0c;使用Excel插件就足够了&#xff01; Excel插件&#xff0c;tusimpleBI 是一款 Excel 图表插件&#xff0c;提供超过120项图表功能&#xff0c;帮助用户制作各种 Excel 所没有的高级图表&#xff0c;轻轻松松一键出图。 它能够制作10…

VUE3 组件通信

props 用途&#xff1a;可以实现父子组件、子父组件、甚至兄弟组件通信 父组件 <template><div><Son :money"money"></Son></div> </template><script setup lang"ts"> import Son from ./son.vue import { re…

量子加速超算简介

量子加速超算简介 有用的量子计算的发展是全球政府、企业和学术界的巨大努力。 量子计算的优势可以帮助解决世界上一些与材料模拟、气候建模、风险管理、供应链优化和生物信息学等应用相关的最具挑战性的问题。 要实现量子计算的优势&#xff0c;需要将量子计算机集成到现有的…

容器部署对比:通用容器部署 vs 使用腾讯云容器镜像服务(TCR)部署 Stable Diffusion

目录 引言1 通用容器部署的主要步骤1.1 准备环境1.2 构建 Docker 镜像1.3 上传镜像1.4 部署容器1.5 配置网络1.6 监控和维护 2 使用腾讯云容器镜像服务&#xff08;TCR&#xff09;部署的主要步骤2.1 下载 Stable Diffusion web UI 代码2.2 制作 Docker 镜像2.3 上传镜像到 TCR…

Scala--02--IDEA编写Hello World

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.Scala 插件安装1&#xff09;插件离线安装步骤2&#xff09; 插件在线安装&#xff08;推荐可选&#xff09; 2.HelloWorld 案例1&#xff09;打开 IDEA->点击…

Javaweb学习记录(三)请求响应案例

下面为一个请求响应案例&#xff0c;postman发送请求&#xff0c;服务器响应将一个xml文件中的数据通过读取解析&#xff0c;将其用Result类标准的格式返回前端&#xff0c;在前端用json的方式显示 后端Controller代码 1、通过本类的字节码文件得到类加载器并寻找到需要解析的…

Jenkins-pipeline流水线构建完钉钉通知

添加钉钉机器人 在钉钉群设置里添加机器人拿出Webhook地址&#xff0c;设置关键词 Jenkins安装钉钉插件 Dashboard > 系统管理 > 插件管理&#xff0c;搜索构建通知&#xff0c;直接搜索Ding Talk也行 安装DingTalk插件&#xff0c;重启Jenkins 来到Dashboard > 系…

汽车专业翻译应该如何进行呢?

随着全球汽车行业的不断发展&#xff0c;大量的汽车业相关技术资料、产品说明、会议交流、推广分享等都需要进行语言转换&#xff0c;进而促进了汽车翻译业务的需求旺盛。那么&#xff0c;汽车专业翻译应该如何进行呢&#xff0c;北京哪个翻译公司比较好&#xff1f; 业内人士指…

Webpack学习记录

记录学习笔记&#xff0c;欢迎指正 1.大型项目为什么需要打包 1.1 使用打包工具原因 编译或转译文件&#xff1a; 项目中可能用到ES6语法&#xff0c;可能有浏览器不支持。需要打包工具将代码编译输出为ES5语法的代码。项目中可能使用Sass&#xff0c;Less等预处理器&#xff…

【Selenium(一)】

简介 Selenium是一个开源的自动化测试工具&#xff0c;主要用于Web应用程序的自动化测试。它支持多种浏览器&#xff0c;包括Chrome、Firefox、Internet Explorer等&#xff0c;以及多种编程语言&#xff0c;如Java、Python、C#、Ruby等&#xff0c;使得它成为Web自动化测试中…