Springboot 三层架构(Controller(控制层)、Dao(数据访问层)、Service(业务逻辑层))

server/2025/1/21 17:19:47/

文章目录

  • 开发Stringboot一个功能的流程
  • Springboot 三层架构
  • 一、Controller(控制层)
    • Controller(控制层)的作用
    • 1、如何创建Controller(控制层)
    • 2、在Controller(控制层)中如何调用Service(业务逻辑层)
  • 二、Service(业务逻辑层)
    • Service(业务逻辑层)的作用:
    • 1、创建Service(业务逻辑层)
    • 2、为什么要去创建接口Service与实体Service
    • 3、如何确定调用的是哪一个实体Service(业务逻辑层)的方法?
      • 依赖注入(Dependency Injection,简称:DI)
      • @Autowired与@Resource的区别:
  • 三、Dao(Data Access Object:数据访问层)[也称:持久层]
    • Dao(Data Access Object:数据访问层)[也称:持久层] 的作用:
    • 1、如何创建Dao(数据访问层/持久层)
    • 2、持久层是如何将数据存储在Bean容器中
  • 三层架构、客户端之间的关系
    • 概述
    • 图形化示意图
  • Spring IOC与Bean容器


开发Stringboot一个功能的流程

开发流程:
查看页面原型明确需求(一般为项目经理提供) >> 阅读接口文档 >> 思路分析 >> 接口开发 >> 接口测试 >> 前后端联调
在这里插入图片描述

Springboot 三层架构

概念:当有大量的对数据的逻辑处理时,会发现代码会有大量的重复性,且非常的繁琐,这时可以使用三层架构去将代码进行拆分成三个架构(Controller(控制器)、Service(服务)、Dao(数据访问)。
软件设计原则:高内聚底耦合,那什么高内聚底耦合呢?
内聚:软件中各个功能模块内部的功能联系。
耦合:衡量软件中各个 层 / 模块 之间的依赖、关联的程度。
为什么要创建三层架构:在实际开发中要如何满足高内聚低耦合呢?这时就可以用到了Springboot中的三层架构,可以有效的避免耦合,而提高内聚,所以在开发Springboot时我们一般都会使用三层架构形式去创建项目。
注意:在后期的开发中我们一般会是一个对象负责一个作用,尽量遵守“单一职责原则”。

一、Controller(控制层)

Controller(控制层)的作用

Controller(控制层、又称:表现层)一般是用来接收前端发来的请求,并对此请求进行判断需要调用Service(业务逻辑层)中的那个实体类方法,调用完之后Service会返回处理完之后的数据给Controller(控制层、又称:表现层),此时它在返回数据给前端做出响应,(且返回的类型为JSON类型,也就是满足HTTP协议的返回值,一般会创建一个Result类进行规范返回类型)

1、如何创建Controller(控制层)

  1. 创建Controller类并标注注解@RestController

@RestController此注解是在运行代码时,容器会提供该类型的bean对象,并赋值改变变量——简单来说就是将调用容器中的变量

//实例:
@RestController
public class DeptController {}
  1. 再次类中创建一个属性用来连接Service并使用@Autowired注解进行标注

@Autowired此注解是用来调用Service在Bean容器中所存储的数据。

//实例:
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;
}
  1. 创建一个返回值为Result的方法,并使用@RequestMapping注解进行标注,并给此属性赋值

@RequestMapping此注解是设置指定的访问的URL,且返回值必须是满足HTTP协议格式的数据,一般会设定为JSON格式。
Result是自己定义的一个类,而此类中是严格按照HTTP协议来进新编写的。

//实例:
@RestController
public class DeptController {@Autowiredprivate DeptService deptService;@RequestMapping("/depts")public Result list(){}
}
//Result代码实例:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {private Integer code;//响应码,1 代表成功; 0 代表失败private String msg;  //响应信息 描述字符串private Object data; //返回的数据//增删改 成功响应public static Result success(){return new Result(1,"success",null);}//查询 成功响应public static Result success(Object data){return new Result(1,"success",data);}//失败响应public static Result error(String msg){return new Result(0,msg,null);}
}
  1. 在上面的方法中去调用Service中的方法来去返回值

当客户端进行访问到此方法时,表明是需要返回数据或者对数据的修改等,所以再次方法中就要去调用Service中可以完成此要求的对应的方法。
(注意:在Service中可以完成此操作的方法也是需要自己在Service层去创建,因为Controller层只做接收前端请求和响应完成好的数据,所以此方法要交给Service层进行数据处理。)

@RestController
public class DeptController {@Autowiredprivate DeptService deptService;@RequestMapping("/depts")public Result list(){List<Dept> DeptList = deptService.listDept();//此Service中的方法是查询数据的方法,所以返回的数据会是一个数组或者字典return Result.success(DeptList);}
}

2、在Controller(控制层)中如何调用Service(业务逻辑层)

在你写SpringBoot项目时你可能会有疑问,控制层到底是通过什么来去访问业务逻辑层的,其实此疑问在上面已经给出答案了,就是使用注解@Autowired来去调用的,但是它并不是去直接调用的,它是去调用业务逻辑层储存在Bean容器中的方法,哪为什么不直接去调用业务逻辑层中实体类的方法呢?这个其实上面也给出了答案,在开发软件时我们所遵守的原则是高内聚低耦合,如果去直接调用的话就会违背了低耦合的原则,所以需要去使用Bean容器进行存储与调用,这样子就避免了耦合

二、Service(业务逻辑层)

Service(业务逻辑层)的作用:

业务逻辑层一般是对从数据库中所拿到的数据进行逻辑处理,再将处理完之后的数据存储在Bean容器中,这样可有有效的避免耦合性。

1、创建Service(业务逻辑层)

  1. 创建一个接口,并在创建一个方法,方便后面的实体类使用。

此接口是为了方便后续业务逻辑层的复用性。

//代码实例:
public interface DeptService {public List<Dept> listDept();
}
  1. 创建一个由@Service注解标记的类去实现上面的接口

@Service注解是用来,将此类中的方法及属性都存放在Bean容器中,

//代码实例:
@Service
public class DeptServiceImpl implements DeptService {
}
  1. 创建属性并使用@Autowired注解标识,获取到数据访问层中的数据

调用方式也是从Bean容器中调用的。

@Service
public class DeptServiceImpl implements DeptService {@Autowiredprivate DeptMapper deptMapper;
}
  1. 进行重写接口中的方法,此方法是用来完成单个业务逻辑。

注意在这里可以使用@Override注解可以避免在重写方法时发生错误。

//代码实例
@Service
public class DeptServiceImpl implements DeptService {@Autowiredprivate DeptMapper deptMapper;@Overridepublic List<Dept> listDept() {//......}
}

2、为什么要去创建接口Service与实体Service

业务逻辑层中一般都会创建一个接口和多个实体类,而为什么要创建接口,而不是直接去创建一个类来将业务逻辑层中的代码写进此类里面?因为当你去以一个类来去存储所有的业务逻辑层的代码时,会有
弊端:
1、你会发现每一个实现逻辑方法中都会用大量重复的代码。
2、在你去调用业务逻辑层的方法时你会发现没有统一的类去接收业务逻辑层中的数据。
3、而且他也违反了“单一职责原则(一个类只办一件事)。
而使用接口业务逻辑层可以奖上面的缺点都完美的补全。所以一般在创建业务逻辑层时都会先创建接口再去创建实体类。
(创建接口业务逻辑层是如何补全上面的缺点的):
1、在使用接口业务逻辑层时可以,直接在接口中创建规范方法来去避免重复创建方法的弊端。
2、这里再调用业务逻辑层时可以直接使用多态来去避免上面的弊端“2”
3、而上述弊端“3”可以创建多个类进行避免。

3、如何确定调用的是哪一个实体Service(业务逻辑层)的方法?

当你在写SpringBoot项目时肯定会遇到,有很多的实体类Service(也就相当于有许多的逻辑方法),而此时我要如何去调用我所想要的哪一个方法?
这个时候再调用Service时就要去了解依赖注入是什么了:

依赖注入(Dependency Injection,简称:DI)

概念:**“容器”**为应用程序提供运行时,所依赖的资源,称作“依赖注入
DI的简单使用:当需要调用Bean里面的对象时,再代码上方使用功能@Autowired(自动接线)标记

Bean注入类型:

  1. @Autowired

概念:默认是按照类型进行连接,如果存在多个相同类型的bean,将会报错。
使用方法:在需要调用的类上面进行标识即可

代码实例:

//Controller层调用Service层代码
@Autowired
private EmpService empService;//Service层的类型
  1. @Primary

概念:当有两个相同类型时,可以使用此注解进行标识对应的类。
使用方法:这个注解需要配合@Autowired注解一起使用,当@Autowired注解已经标识后,再去找你所需要Service层对应的实体类进行标识,并在此类上面进行标识

代码实例:

//Controller层调用Service层代码
@Autowired
private EmpService empService;//Service层的类型
//Service实体类代码进行标识
@Primary//使用此标识之后在调用Service层时就会执行此类
@Service //口岸个当前类交给ICO容器管理,成为IOC容器的bean
public class EmpServiceA implements EmpService{
//...(Service实现逻辑的方法代码)
}
  1. @Qualifier

概念:当有多个相同类型时,可以使用此注解进行选定所需要bean对象。
使用方法:在@Autowired的基础上再添加此注解@Qualifer,并在给他进行赋上你所需要调用的Service层中的实体类对应的bean名。(bean名默认是类名首字母小写)
【原理就是使用spring架构中的BeanFactory.getBean(“beanName”,Object.clss)方法,在原有的根据类型查找对象的@Autowired注解上,增加了通过beanName来进行查找】

代码实例:

//Controller层调用Service层代码
@Qualifier("empServiceA")//输入Service的bean名(默认bean名首字母小写)
@Autowired
private EmpService empService;//Service层的类型
  1. @Resourcce

概念:当有多个相同类型时,可以使用此注解进行选定所需要bean对象。
使用方法:此注解不需要与@Autowired注解联合使用,它可以直接进行调用,当有多个相同类型时,可以使用此注解中的name属性赋值(对应的bean名)即可调用。

代码实例:

//Controller层调用Service层代码
@Resourcce(name = "empServiceA")//将注解@Resource的name属性赋值
private EmpService empService;//Service层的类型

@Autowired与@Resource的区别:

  1. @Autowired是Spring框架提供的注解,而@Resource是JDK提供的注解。
  2. @Autowired默认是按照类型注入,而@Resource默认是按照名称注入。(若是了解过Spring的话就知道这里的原理就是先根据[BeanFactory.getBean(“name”/Object.class)] 类型\名称 去找到相对应的对象,再去进行注入[创建bean.xml,在进行注入])

三、Dao(Data Access Object:数据访问层)[也称:持久层]

Dao(Data Access Object:数据访问层)[也称:持久层] 的作用:

数据访问层此层是用来对数据库中的数据进行增删改查,并将整理好的数据进行动态的将数据存放在Bean容器中。也就是在我前面几章中所讲的Mybatis,它就是持久层中的一种类型,当然还有其他类型的操作类型,这里只讲Mybatis这款持久型架构

1、如何创建Dao(数据访问层/持久层)

这里因为在前面几个章节已经详细的讲解了如何创建持久层(Mybatis)这里就不在做演示了,若是不太熟悉Mybatis的可以看前面的几个关于Mybatis的章节,相信应该会对你有一些帮助。

2、持久层是如何将数据存储在Bean容器中

持久层是使用注解@Mapper来去完成将数据动态的将数据存储在Bean容器中。
@Mapper(映射):映射的作用是:在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理

三层架构、客户端之间的关系

概述

客户端向服务端发起请求,由控制层接收并调用业务逻辑层中的方法,在处理逻辑时会对数据库中的数据进行调用,这时就要去调用数据访问层数据访问层将会把查询到的数据进行传递给业务逻辑层,而此时的数据需要做逻辑处理,处理完毕之后,在传递给控制层,这时客户端的数据已经拿到了,但是不能直接去传递,需要将数据以HTTP协议的规范进行传递(可以直接创建一个Result类进行单独处理),规范完之后,在传递给客户端
注意:上述中的“传递”是将数据存储在Bean容器后,在去调用Bean容器中对应的数据,不是直接进行传递,因为这样会有耦合

图形化示意图

在这里插入图片描述

Spring IOC与Bean容器

在Spring中,构成应用程序主干并由SpringIOC容器管理的对象称为bean。 bean是一个由SpringIOC容器实例化、组装和管理的对象。 否则,bean只是应用程序中许多对象之一。 bean以及它们之间的依赖关系反映在容器使用的配置元数据中。
你可以理解为:IOC容器是用来管理bean对象的,但是IOC并没有实体化,他更像是抽象化的概念,而多个bean对象是此抽象化的实体化。
若是想深入了解 Spring IOC与Bean容器,可以去观看“大白话讲解Spring的@bean注解”这篇文章。


上述文章是我查看一些资料之后,在结合自己的理解进行编写的,所以可能会有一些不足,还请谅解,若是发现了一些错误还请大佬们指出,我会非常感谢!!!


http://www.ppmy.cn/server/160241.html

相关文章

基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战

目录 前言 一、PostGIS空间求解 1、相邻的求解 二、后台程序实现 1、数据查询的实现 2、API接口实现 三、WebGIS可视化实现 1、空间面展示 2、增加面标注 3、图例展示 4、与缅甸距离较近的区县信息 四、总结 前言 云南&#xff0c;这个位于中国西南边陲的省份&…

数据分析的新利器-微软开源的GraphRAG

微软的GraphRAG是一种结合了图结构和检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术的先进框架&#xff0c;旨在提升大型语言模型&#xff08;LLM&#xff09;在处理复杂问题时的性能。GraphRAG通过构建知识图谱&#xff0c;将非结构…

程序设计安全方案,软件开发安全指南,信息系统安全管理规范(Word原件)

2.1.应用系统架构安全设计要求 2.2.应用系统软件功能安全设计要求 2.3.应用系统存储安全设计要求 2.4.应用系统通讯安全设计要求 2.5.应用系统数据库安全设计要求 2.6.应用系统数据安全设计要求 软件全套精华资料包清单部分文件列表&#xff1a; 工作安排任务书&#xff0c;可行…

进阶——第十六届蓝桥杯熟练度练习(串口)

USART是&#xff08;通用同步异步收发器&#xff09; UART是&#xff08;通用异步收发器&#xff09; 单片机作为主机发送数据到从机 代码包含 /* Includes ------------------------------------------------------------------*/ #include "main.h" #include &q…

Android Http基础:图片下载并显示和WebView的应用

<RelativeLayout xmlns:android“http://schemas.android.com/apk/res/android” xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_parent"android:layout_height"match_parent"android:paddingLeft"dimen/ac…

cmake 可使用的构建系统

cmake 可使用的构建系统 ChatGPT 说&#xff1a; ChatGPT CMake 支持多种构建系统&#xff0c;允许用户根据其开发环境选择适合的构建工具。以下是 CMake 常用的构建系统和生成器&#xff1a; 1. Visual Studio 系列 适用于 Windows 环境的 Visual Studio 构建系统&#xf…

PyTest自学-认识PyTest

1 PyTest自学-认识PyTest 1.1 PyTest可以用来做什么&#xff1f; PyTest是一个自动化测试框架&#xff0c;支持单元测试和功能测试&#xff0c;有丰富的插件&#xff0c;如&#xff0c;pytest-selemium, pytest-html等。 1.2 安装pytest 使用pip install -U pytest。 1.3 py…

Node.js 到底是什么

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它允许开发者使用 JavaScript 编写服务器端代码。 一、主要特点 1. 事件驱动和非阻塞 I/O 模型 Node.js 采用事件驱动架构&#xff0c;通过回调函数处理 I/O 操作&#xff0c;这使得它在处理大量并发请…