Spring Boot 后端分层开发实战:从 MVC 到三层架构详解

Spring Boot 后端分层开发实战:从 MVC 到三层架构详解

应用分层

通过上面的练习,我们学习了 Spring MVC 简单功能的开发,但是我们也发现了一些问题。目前我们程序的代码有点 “杂乱”,然而当前只是 “一点点功能” 的开发。如果我们把整个项目功能完成呢?代码会更加的 “杂乱无章”(文件乱,代码内容乱)。

也基于此,咱们接下来学习应用分层。类似公司的组织架构:公司初创阶段,一个人身兼数职,既做财务,又做人事,还有行政。随着公司的逐渐壮大,会把岗位进行细分,划分为财务部门,人事部门,行政部门等。各个部门内部还会再进行细分。

项目开发也是类似,最开始功能简单时,我们前后端放在一起开发,随着项目功能的复杂,我们分为前端和后端不同的团队,甚至更细粒度的团队。后端开发也会根据功能再进行细分。MVC 就是其中的一种拆分方式。但是随着后端人员不再涉及前端,后端开发又有了新的分层方式。

4.1 介绍

阿里开发手册中,关于工程结构部分,定义了常见工程的应用分层结构:

那么什么是应用分层呢?应用分层是一种软件开发设计思想,它将应用程序分成 N 个层次,这 N 个层次分别负责各自的职责,多个层次之间协同提供完整的功能。根据项目的复杂度,把项目分成三层,四层或者更多层。常见的 MVC 设计模式,就是应用分层的一种具体体现。

为什么需要应用分层?在最开始的时候,为了让项目快速上线,我们通常是不考虑分层的。但是随着业务越来越复杂,大量的代码混在一起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动一处就牵一发而动全身等问题。所以学习对项目进行分层就是我们程序员的必修课了。

如何分层(三层架构)

咱们上一节中学习的 “MVC”,就是把整体的系统分成了 Model(模型),View(视图)和 Controller(控制器)三个层次,也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是一种标准的软件分层架构。

目前现在更主流的开发方式是 “前后端分离” 的方式,后端开发工程师不再需要关注前端的实现,所以对于 Java 后端开发者,又有了一种新的分层架构:把整体架构分为表现层、业务逻辑层和数据层。这种分层方式也称之为 “三层架构”。

  1. 表现层:就是展示数据结果和接受用户指令的,是最靠近用户的一层;
  2. 业务逻辑层:负责处理业务逻辑,里面有复杂业务的具体实现;
  3. 数据层:负责存储和管理与应用程序相关的数据。

可以看到,咱们前面的代码,并不符合这种设计思想,而是所有的代码堆砌在一起。

这三个部分,在Spring的实现中,均有体现:

按照上面的层次划分,Spring MVC 站在后端开发人员的角度上,也进行了支持,把上面的代码划分为三个部分:

  • 请求处理、响应数据:负责,接收页面的请求,给页面响应数据。
  • 逻辑处理:负责业务逻辑处理的代码。
  • 数据访问:负责业务数据的维护操作,包括增、删、改、查等操作。

这三个部分,在 Spring 的实现中,均有体现:

  • Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
  • Service:业务逻辑层。处理具体的业务逻辑。
  • Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

MVC 和三层架构的区别和联系

关于二者的关系,一直存在不同的观点。有人认为三层架构是 MVC 模式的一种实现,也有人认为 MVC 是三层架构的替代方案,等等各种说法都有。根本原因是大家站在不同的角度来看待这个问题的。

JavaEE 部分的学习重在 “实践”,大家根据自己的理解,能够自圆其说,说出自己的观点即可,也不建议大家去背书。

从概念上来讲,二者都是软件工程领域中的架构模式。

  • MVC 架构模式由三部分组成,分别是:模型 (Model),视图 (View) 和控制器 (Controller)。
  • 三层架构将业务应用划分为:表现层,业务逻辑层,数据访问层。

MVC 中,视图和控制器合起来对应三层架构中的表现层。模型对应三层架构中的业务逻辑层、数据层,以及实体类。

二者其实是从不同角度对软件工程进行了抽象。

  • MVC 模式强调数据和视图分离,将数据展示和数据处理分开,通过控制器对两者进行组合。
  • 三层架构强调不同维度数据处理的高内聚和低耦合,将交互界面、业务处理和数据库操作的逻辑分开。

角度不同也就谈不上互相替代了,在日常的开发中可以经常看到两种共存的情况,比如我们设计模型层的时候往往也会拆分出业务逻辑层(Service 层)和数据访问层(Dao 层)。

但是二者的目的是相同的,都是 “解耦,分层,代码复用”。

软件设计原则:高内聚低耦合

  • 高内聚:指的是一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 “高内聚”。
  • 低耦合:指的是软件中各个层、模块之间的依赖关联程序越低越好。修改一处代码,其他模块的代码改动越少越好。

高内聚低耦合矛盾吗?不矛盾,高内聚指的是一个模块中各个元素之间的联系的紧密程度,低耦合指的是各个模块之间的紧密程度。

这就好比一个企业,包含很多部门,各个部门之间的关联关系要尽可能的小,一个部门发生问题,要尽可能对降低对其他部门的影响,就是耦合。但是部门内部员工关系要尽量紧密,遇到问题一起解决,克服。这叫做内聚。

比如邻里邻居,楼上漏水,楼下遭殃,就是耦合。家庭一个成员生病,其他成员帮忙照顾,就叫内聚。一个家庭内部的关系越紧密越好,一个家庭尽可能少的影响另一个家庭,就是低耦合。

4.2 代码重构

我们使用上面的分层思想,来对代码进行改造

  1. 先创建对应的包路径,并把代码移到对应的目录
    • com.example.demo.controller
    • com.example.demo.service
    • com.example.demo.dao
    • com.example.demo.model

1. 代码拆分

控制层(Controller)

接收前端发送的请求,对请求进行处理,并响应数据。

package com.example.demo.controller; import com.example.demo.model.BookInfo; import com.example.demo.service.BookService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RequestMapping("/book") @RestController public class BookController { @RequestMapping("/getList") public List<BookInfo> getList() { BookService bookService = new BookService(); // 获取数据 List<BookInfo> books = bookService.getBookList(); return books; } } 
业务逻辑层(Service)

处理具体的业务逻辑。

import com.example.demo.dao.BookDao; import com.example.demo.model.BookInfo; import java.util.List; public class BookService { public List<BookInfo> getBookList() { BookDao bookDao = new BookDao(); List<BookInfo> books = bookDao.mockData(); for (BookInfo book : books) { if (book.getStatus() == 1) { book.setStatusCN("可借阅"); } else { book.setStatusCN("不可借阅"); } } return books; } } 
数据访问层(Dao)

负责数据访问操作,包括数据的增、删、改、查。

import com.example.demo.model.BookInfo; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Random; public class BookDao { /** * 数据Mock 获取图书信息 * @return */ public List<BookInfo> mockData() { List<BookInfo> books = new ArrayList<>(); for (int i = 0; i < 5; i++) { BookInfo book = new BookInfo(); book.setId(i); book.setBookName("书籍"+i); book.setAuthor("作者"+i); book.setCount(i*5+3); book.setPrice(new BigDecimal(new Random().nextInt(100))); book.setPublish("出版社"+i); book.setStatus(1); books.add(book); } return books; } } 

4.3 应用分层的好处

  • 降低层与层之间的依赖,结构更加明确,利于各层逻辑的复用
  • 开发人员可以只关注整个结构中的其中某一层,极大地降低了维护成本和维护时间
  • 可以很容易的用新的实现来替换原有层次的实现
  • 有利于标准化

4.4  企业规范

课件中出现的企业规范,适用于多数企业,均不做强制要求。具体以所在企业为准。
  1. 类名使用大驼峰风格,但以下情形例外:DO/BO/DTO/VO/AO
  2. 方法名、参数名、成员变量、局部变量统一使用小驼峰风格
  3. 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。
常见命名风格介绍
  • 大驼峰:所有单词首字母都需要大写,又叫帕斯卡命名法,比如: UserController
  • 小驼峰:除了第一个单词,其他单词首字母大写,比如: userController
  • 蛇形:用下划线 (_) 作用单词间的分隔符,一般小写,又叫下划线命名法,比如: user_controller
  • 串形:用短横线 (-) 作用单词间的分隔符,又叫脊柱命名法,比如: user-controller

4.5 总结

  1. 学习 Spring MVC,其实就是学习各种 Web 开发需要用到的注解:
    • @RequestMapping:路由映射
    • @RequestParam:后端参数重命名
    • @RequestBody:接收 JSON 类型的参数
    • @PathVariable:接收路径参数
    • @RequestPart:上传文件
    • @ResponseBody:返回数据
    • @CookieValue:从 Cookie 中获取值
    • @SessionAttribute:从 Session 中获取值
    • @RequestHeader:从 Header 中获取值
    • @Controller:定义一个控制器,Spring 框架启动时加载,把这个对象交给 Spring 管理。默认返回视图。
    • @RestController@ResponseBody + @Controller,返回数据
  2. Cookie 和 Session 都是会话机制,Cookie 是客户端机制,Session 是服务端机制。二者通过 SessionId 来关联。Spring MVC 内置HttpServletRequestHttpServletResponse两个对象。需要使用时,直接在方法中添加对应参数即可,Cookie 和 Session 可以从HttpServletRequest中来获取,也可以直接使用HttpServletResponse设置 Http 响应状态码。
  3. Java EE 学习阶段会涉及较多工具、插件的学习,来帮助我们提高开发效率。比如 Postman、lombok、EditStarter,后面还会继续学习其他的工具或插件。

注意事项:

Spring , SpringBoot , SpringMVC 之间的关系以及区别?

名称定位核心作用
Spring Framework基础框架提供 IoC(控制反转)、DI(依赖注入)、AOP(面向切面编程)等核心能力,是整个 Spring 生态的基石。
Spring MVCWeb 框架基于 Spring 的 Web 层解决方案,专注于处理 HTTP 请求、路由、视图渲染等 Web 开发任务。
Spring Boot快速开发框架基于 Spring 和 Spring MVC,通过 “约定大于配置” 的思想,简化配置、内置服务器、自动装配,让开发者快速搭建可独立运行的应用。

二、它们之间的联系

  1. Spring 是基础Spring MVC 和 Spring Boot 都构建在 Spring Framework 之上,依赖它的核心功能(如 IoC 容器)。
  2. Spring MVC 是 Spring 的 Web 模块早期开发 Web 应用时,需要手动配置大量 XML,整合 Spring 和 Spring MVC,步骤繁琐。
  3. Spring Boot 是对 Spring 和 Spring MVC 的封装与简化
    • 它自动配置了 Spring MVC 的常用组件(如 DispatcherServlet、视图解析器)。
    • 内置了 Tomcat 等 Web 服务器,无需单独部署。
    • 通过 starter 依赖,一键引入 Spring MVC 等模块,大幅减少配置和依赖管理的工作量。

三、它们之间的区别

维度Spring FrameworkSpring MVCSpring Boot
核心目标提供企业级 Java 开发的通用解决方案专注于 Web 层开发简化 Spring 应用的开发和部署
配置方式大量 XML 或 JavaConfig 配置依赖 Spring 的配置,需额外配置 Web 相关组件自动配置(Auto-Configuration),极少手动配置
部署方式需要部署到外部 Web 服务器需要部署到外部 Web 服务器内置服务器,可直接运行 JAR 包
依赖管理手动管理依赖,易出现版本冲突手动管理依赖通过 starter 自动管理依赖和版本
使用场景所有需要 IoC、AOP 等能力的 Java 应用传统的 Spring Web 应用开发快速开发微服务、独立应用、RESTful API

四、一句话总结

  • Spring 是 “地基”,提供了最核心的编程模型和能力。
  • Spring MVC 是 “房子的框架”,专门用来盖 Web 应用这栋楼。
  • Spring Boot 是 “精装修套餐”,把地基和框架都准备好了,你只需要拎包入住,快速开发。

Read more

部署OpenClaw首选远程软件——UU远程:从准备到落地,新手也能轻松上手

部署OpenClaw首选远程软件——UU远程:从准备到落地,新手也能轻松上手

前言 在企业为客户远程部署、技术博主带粉丝实操教学、远程技术支持等真实场景中,稳定、低延迟、高同步的远程工具是完成 AI 工具部署的关键。本地部署无需依赖云服务器,成本更低、更安全,但传统远程软件往往延迟高、操作卡顿,严重影响部署效率与体验。 本文将以OpenClaw轻量 AI 辅助服务工具为部署对象,全程依托网易 UU 远程实现流畅远程控制与协助,详细讲解网易 UU 远程的核心优势,从 UU 远程环境准备、OpenClaw 远程部署,到基于网易UU远程的实时监视 OpenClaw 状态,零门槛、无复杂配置。借助网易 UU 远程的低延迟与高稳定性,企业可高效为客户远程交付,博主可轻松带粉丝同步实操,新手也能跟着完整落地。 本篇文章分别从准备工作、远程部署、远程监视三个维度进行实操教学,一步步拆解如何运用远程UU进行远程部署openclaw。 一、网易UU远程介绍 网易UU远程是网易出品的一款轻量化、零配置、高稳定的远程控制工具,区别于传统远程工具(

By Ne0inhk
《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》

《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》

前引:这是一个聚焦基础搜索引擎核心工作流的实操项目,基于 C/C++ 技术生态落地:从全网爬虫抓取网页资源,到服务器端完成 “去标签 - 数据清洗 - 索引构建” 的预处理,再通过 HTTP 服务接收客户端请求、检索索引并拼接结果页返回 —— 完整覆盖了轻量级搜索引擎的端到端逻辑。项目采用 C++11、STL、Boost 等核心技术栈,搭配 CentOS 7 云服务器 + GCC 编译环境(或 VS 系列开发工具)部署,既适配后端工程的性能需求,也能通过可选的前端技术(HTML5/JS 等)优化用户交互,是理解搜索引擎底层原理与 C++ 工程实践的典型案例 目录 【一】Jieba分词工具 【二】正/倒排索引结构设计

By Ne0inhk

前端 | 一篇搞懂CSS盒模型核心:padding、margin、border与box-sizing、border-radius

一篇搞懂CSS盒模型核心:padding、margin、border与box-sizing、border-radius 写CSS布局时,很多人会被“盒子”里的padding、margin、border绕晕——明明设置了相同的宽度,加个padding就变形;调整margin又莫名影响相邻元素;border的宽度到底算不算总宽度?其实只要把“盒子”的逻辑拆透,这些问题都能迎刃而解。今天就用最直白的方式,把这些核心概念讲清楚,让你看完就能直接用。 先分清三个“间隔”:padding、margin、border的核心区别 CSS里的每个元素,都像一个“快递盒子”——内容是盒子里的物品,而padding、margin、border,就是盒子本身和周围的不同间隔。三者的核心区别,本质是“位置不同、作用对象不同、是否占盒模型空间不同”,用一句话总结:border是盒子的“壳”,padding是壳和内容的“内填充”,margin是盒子和其他盒子的“外距离”。 1. border:盒子的“

By Ne0inhk
基于YOLO26/11/v8算法的Web目标检测系统,人脸表情识别系统,Django+Vue3 的前后端分离,实现摄像头实时识别,YOLO26/YOLO11/v8 + LLM大模型智能分析,科研必备

基于YOLO26/11/v8算法的Web目标检测系统,人脸表情识别系统,Django+Vue3 的前后端分离,实现摄像头实时识别,YOLO26/YOLO11/v8 + LLM大模型智能分析,科研必备

✨ 更新日志 * ✔️ 2026/3/3,2.0 版本,前端导航栏改为侧边栏系统,视频流采用websocket框架延迟更低, YOLO26/YOLO11/YOLOv8 视频流更稳定,在之前的系统增加 LLM 大模型智能分析,是科研必备,支持 YOLO26/11/v8 分类模型、目标检测、分割、obb、关键点检测任务,还支持双模型联合检测与识别,如人脸表情识别、人脸识别等一些识别任务需要检测模型与分类模型共同完成,在人脸表情识别中,单独使用检测模型去识别人脸表情也不是不可以,但有一个问题数据集如果全是头部照片的话,当模型预测的照片是全身照片时,模型识别准确率就没有这么高了, 那么这时候可以用检测模型识别人脸,把人脸信息输入到表情分类模型进行分类即可,反正这是一个通用的系统,更换自己模型即可,大家懂得都懂的,更多功能看下文即可。 摘要 在人工智能迈向通用化(AGI)的今天,“视觉感知 + 语言理解”的多模态联合是未来的趋势。单纯的检测画框已经无法满足复杂的业务需求,如何让系统“看懂”

By Ne0inhk