我以为我对Spring MVC很了解,直到我遇到了...

news2024/9/23 7:33:04

点赞再看,Java进阶一大半

所有人都知道Spring MVC是Rod Johnson是开发的,却鲜有人知道Spring MVC的理论基础来自于1978 年提出MVC模式的一个老头子,他就是Trygve Mikkjel Heyerdahl Reenskaug,挪威计算机科学家,奥斯陆大学名誉教授。

Trygve Reenskaug的MVC架构思想早期用于图形用户界面(GUI) 的软件设计,他对MVC是这样解释的。

MVC 被认为是解决用户控制大型复杂数据集问题的通用解决方案。最困难的部分是为不同的架构组件想出好的名字。模型-视图-编辑器是第一个。经过长时间的讨论,特别是与Adele Goldberg的讨论,我们最终采用了模型-视图-控制器这个术语。

大家可以看看下面Trygve Reenskaug对MVC架构思想的理解与介绍。

在这里插入图片描述

在这里插入图片描述

大家好,我是南哥。

一个Java进阶的领路人,今天指南的是Spring MVC,跟着南哥我们一起Java进阶。

本文收录在我开源的《Java进阶指南》中,一份帮助小伙伴们进阶Java、通关面试的Java学习面试指南,相信能帮助到你在Java进阶路上不迷茫。南哥希望收到大家的 ⭐ Star ⭐支持,这是我创作的最大动力。GitHub地址:https://github.com/hdgaadd/JavaProGuide。

文章目录

    • 1. Spring MVC概况
      • 1.1 如何理解Spring MVC
    • 2. Spring MVC技术要点
      • 2.1 Spring MVC工作流程
      • 2.2 Spring MVC搭配Tomcat容器
      • 2.3 Spring MVC常见注解

1. Spring MVC概况

1.1 如何理解Spring MVC

大家都知道Spring MVC很强大,南哥问大家一个问题,Spring MVC为什么会出现?一项技术的出现必定是为了解决旧技术考虑不全所积累的软件熵。《程序员修炼之道》在软件的熵一节中对熵的解释很有冲击力,作者是这么说的,大家有没什么触动。

虽然软件开发不受绝大多数物理法则的约束,但我们无法躲避来自熵的增加的重击。熵是一个物理学术语,它定义了一个系统的“无序”总量。不幸的是,热力学法则决定了宇宙中的熵会趋向最大化。当软件中的无序化增加时,程序员会说“软件在腐烂”。有些人可能会用更乐观的术语来称呼它,即“技术债”,潜台词是说他们总有一天会偿还的——恐怕不会还了。

在没有出现Spring MVC之前,老一代的开发者会在Servlet中编写业务逻辑和控制代码,甚至属于后端的业务逻辑也会耦合在了jSP页面。在当时互联网不流行,业务都比较简单的年代,这样写问题不会太大,但随着时间的累积、互联网的爆发,业务复杂度也爆发式上升,这叫新来的实习生程序员怎么上手呢。缺乏统一和清晰的架构模式,会导致应用程序的可扩展性和可维护性降低。

我们先不讲Spring MVC,把MVC拆解出来。MVC(Model View Controller)实践上是一种软件架构思想,这个思想指导把应用程序分为了三个模块,用于编写业务逻辑的模型、用于数据呈现的视图、用于协调前两者的控制器。

在我们Java程序员第一次接触企业框架时,我们最开始一般用SSM来练练手。如果是SSM框架,充当Model的是编写业务逻辑Java类,充当View的是JSP页面,而充当Controller的则是Servlet。总的来说,MVC明确划分了各个模块的责任,不是你负责的东西不允许越线,这明显维护起来好看多了。

好久好久之前南哥练手的第一个项目是坦克大战,和现在一般企业业务把一个Java对象看出是需求的抽象不同,我当时的坦克大战是把一个Java对象看成是一只坦克的载体。大家第一个Java练手项目有什么故事吗?

2. Spring MVC技术要点

2.1 Spring MVC工作流程

Spring MVC工作流程涉及五大组件,大家先预览一遍:DispatcherServlet、HandleMapping、Controller、ModelAndView、ViewResolver。

第一步用户触发浏览器时将请求发送给前端控制器DispatcherServlet,DispatcherServlet就相当于上文MVC架构的C,Spring源码对DispatcherServlet解释为HTTP请求处理程序/ 控制器的中央调度程序。有了中央调度程序大脑,下一步就可以联调其他组件了。

// DispatcherServlet类
package org.springframework.web.servlet;
public class DispatcherServlet extends FrameworkServlet { }

第二步,DispatcherServlet调用处理器映射器HandleMapping,根据用户请求的URL找到对应的业务控制器Contorller。

// HandlerMapping类
package org.springframework.web.reactive;
public interface HandlerMapping { }

第三步,DispatcherServlet请求处理器适配器HandlerAdapter执行Controller,获得业务结果后返回一个模型视图对象ModelAndView给到DispatcherServlet。

// ModelAndView类
package org.springframework.web.servlet;
public class ModelAndView {
// HandlerAdapter类
package org.springframework.web.servlet;
public interface HandlerAdapter { }

第四步,DispatcherServlet把ModelAndView返回给视图解析器ViewResolver,将ModelAndView解析为视图对象View。

// ViewResolver类
package org.springframework.web.servlet;
public interface ViewResolver {

最后一步,View会负责渲染,同时把结果返回给浏览器。

2.2 Spring MVC搭配Tomcat容器

大家有搭过Spring Web MVC框架的话就有印象,我们要在本机安装单独的一个Tomcat服务器,Tomcat搭配Spring框架才能让我们的Web应用程序跑起来。会不会觉得很麻烦,南哥觉得好麻烦。。

SpringBoot框架则不需要我们单独去部署一个Tomcat服务器,大家甚至在https://start.spring.io/官网下载包后,本地启动就可以把Web程序跑起来,方便吧。

这是为什么?SpringBoot内置了一个Servlet容器,而上文南哥所说的Tomcat容器本质也是一个Servlet容器,SpringBoot默认为我们配置的是Tomcat。要是对Tomcat不满意,你也可以用其他Servlet容器,比如Jetty、Undertow。

Tomcat容器为我们的Spring MVC做了很多脏活,例如底层Socket连接这种麻烦工作。而上文我提到的Spring MVC五大组件本质上都是调用Servlet API,而Servlet API的实现也是由Tomcat容器为我们完成的。

在Spring Web MVC框架里,如果大家要单独部署Servlet容器,切记注意下Spring框架和Servlet 容器的兼容性。在Spring官方文档中,Spring Framework 5.3.x 支持的最后一个Servlet规范版本4.0,从 Spring Framework 6.0 开始,Servlet最低版本为Servlet 5.0。

2.3 Spring MVC常见注解

(1)@Controller和@RestController

把某一个Java类申明为后端接口,我们一般使用@Controller修饰该类,使用@RestController也可以,两者的差异在于后者是@Controller和@ResponseBody的组合,后端接口返回的数据格式会是ResponseBody格式的数据。

大家看下两者的源码解释,南哥把英文注释翻译为了中文。

// 基本 Controller 接口,表示接收HttpServletRequest和HttpServletResponse实例的组件,就像HttpServlet一样,但能够参与 MVC 工作流。
@FunctionalInterface
public interface Controller {
}
// 便捷注释本身带有@Controller和@ResponseBody注释。
// 带有此注释的类型被视为控制器,其中@RequestMapping方法默认采用@ResponseBody语义。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
}

(2)@RequestMapping

这个注解的作用是把请求映射到控制器方法,例如getPerson方法,前端同学请求/persons/{id}就可以控制该方法执行。

@RestController
@RequestMapping("/persons")
class PersonController {

	@GetMapping("/{id}")
	public Person getPerson(@PathVariable Long id) {
		// ...
	}

	@PostMapping
	@ResponseStatus(HttpStatus.CREATED)
	public void add(@RequestBody Person person) {
		// ...
	}
}

HTTP方法有多种请求类型,Spring框架也提供了五种Mapping注解。

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

(3)@RequestParam和、@PathVariable

有个Spring MVC注解相关的小细节,当我们编写有入参的后端接口时,很多同学弄不清楚入参对应的注解要使用什么。

南哥整理了下,如果请求URL类似于localhost:8080/test/?id=6,使用的入参注解是@RequestParam。

  @PostMapping("/test")
  public CommonResult publishCourse(@RequestParam String id) {
  }

如果请求URL类似于localhost:8080/test/6,使用的入参注解是@PathVariable。

  @PostMapping("/test/{id}")
  public CommonResult publishCourse(@PathVariable String id) {
  }

戳这,《JavaProGuide》作为一份涵盖Java程序员所需掌握核心知识、面试重点的Java学习面试指南。

在这里插入图片描述

欢迎关注南哥的公众号:Java进阶指南针。我是南哥,南就南在Get到你的有趣评论➕点赞➕关注。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

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

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

相关文章

【笔记】从零开始做一个精灵龙女-画贴图阶段(上)

此文只是我的笔记,不包全看懂,有问题可评论 PS贴图加工 1.打开ps 拖入uv图,新建图层,设置背景色为灰色,改一下图层名字 2.按z缩小一下uv图层,拖入实体uv图片(目的是更好上色,比如…

第二证券:70万手封单,超3亿元资金盯上这只绩优股

今天A股商场收盘共50股涨停,剔除9只ST股后,41股涨停;25股封板未遂,全体封板率为67.78%。 涨停战场: 超3亿元资金封板盛屯矿业 据证券时报数据宝核算,从收盘涨停板封单量来看,盛屯矿业封单量最…

洛杉矶裸机云大宽带服务器的特性和优势

洛杉矶裸机云大宽带服务器是结合了物理服务器性能和云服务灵活性的高性能计算服务,为用户提供高效、安全的计算和存储能力。在了解如何使用洛杉矶裸机云大宽带服务器之前,需要了解其基本特性和优势。以下是对洛杉矶裸机云大宽带服务器的具体分析&#xf…

短信验证码研究:公开的短信验证码接口、不需要注册的短信验证码接口

短信验证码研究:公开的短信验证码接口、不需要注册的短信验证码接口 0 说明 本文提供了一个短信验证码接口,主要用于以下场景: 1、用于开发调试 2、用于申请验证码困难的企业和个人 3、用于短信验证码认证还没有通过,但是着急…

“论面向方面的编程技术及其应用”写作框架,软考高级论文,系统架构设计师论文

论文真题 针对应用开发所面临的规模不断扩大、复杂度不断提升的问题,面向方面的编程(Aspect Oriented Programming,AOP)技术提供了一种有效的程序开发方法。为了理解和完成一个复杂的程序,通常要把程序进行功能划分和封装。一般系…

uni-app三部曲之三: 路由拦截

1.引言 路由拦截,个人理解就是在页面跳转的时候,增加一级拦截器,实现一些自定义的功能,其中最重要的就是判断跳转的页面是否需要登录后查看,如果需要登录后查看且此时系统并未登录,就需要跳转到登录页&…

Dify工作流中的迭代节点

一.定义 迭代节点的本质就是对数组内容循环处理。对数组执行多次步骤直至输出所有结果。 迭代步骤在列表中的每个条目(item)上执行相同的步骤。使用迭代的条件是确保输入值已经格式化为列表对象。迭代节点允许 AI 工作流处理更复杂的处理逻辑&#xff…

衣服、帽子、鞋子相关深度学习数据集大合集(2)

继续为大家分享关于衣帽鞋子的深度学习数据集,主要有衣服、帽子、鞋子、短裤、短袖、T恤等。 1、人头上带着各种帽子图片数据集 数据格式:图片 是否标注:已标注 标注格式:yolov8 图片数量:1853张 数据查看地址&a…

JavaScript(7)——数组

JavaScript中数组的用法与Java差不多&#xff0c;但还是有一些区别 声明数组 语法: let 数组名 [数据1,数据2,数据...] let arr new Array(数据1,数据2,...数据n) 添加数据 数组.push()方法将一个或多个元素添加到数组末尾&#xff0c;并返回该数组新长度 <script>…

第二证券:销量暴跌95%,这一巨头市值蒸发超3000亿元!

在多重要素刺激下&#xff0c;PCB工作站上风口。 波音销量堕入停滞 6月仅售出3架客机 据央视财经&#xff0c;在一系列丑闻的影响下&#xff0c;波音公司本年出售遭到明显冲击。当地时间9日&#xff0c;波音发布的数据闪现&#xff0c;在以前一个月&#xff0c;该公司仅卖出…

Springcloud双重预防管理体系平台危险作业票子系统-计算机毕业设计源码48672

摘 要 随着企业生产规模的扩大和生产技术的提高&#xff0c;双重预防管理体系逐渐成为企业安全生产的重要手段。在双重预防管理体系中&#xff0c;危险作业票管理是其中的关键环节之一&#xff0c;对于预防生产事故和保障生产安全具有重要作用。 为了更好地管理危险作业票&…

【idea 修改VM配置,无法启动;必杀技】

idea 修改VM配置&#xff0c;无法启动&#xff1b;必杀技 报错信息 error launching idea failed to created JVM 解决方案 不要管你安装的环境在哪&#xff0c;使用了什么破解插件。统统不管用。直接找到C:\Users\YOURWORLD\AppData\Roaming\JetBrains下的idea中的idea64…

常用控件(三)

输入类控件 QLineEditQTextEditQComboBoxQSpinBoxQDateTimeEditQDialQSlider QLineEdit QLineEdit用来表示单行输入框&#xff0c;可以输入一段文本&#xff0c;但是不能换行; 核心属性: 属性说明text输入框中的文本inputMask输入内容格式约束maxLength最大长度frame是否添加边…

Java中实现二维数组(矩阵)的转置

在矩阵运算中&#xff0c;矩阵的转置是一个基本操作&#xff0c;即将矩阵的行变成列&#xff0c;列变成行。在Java中&#xff0c;我们可以通过编写一个方法来实现二维数组的转置。下面&#xff0c;我将详细介绍如何在Java中完成这一任务&#xff0c;并提供完整的代码示例。 编…

java算法day11

二叉树的递归遍历二叉树的非递归遍历写法层序遍历 递归怎么写&#xff1f; 按照三要素可以保证写出正确的递归算法&#xff1a; 1.确定递归函数的参数和返回值&#xff1a; 确定哪些参数是递归的过程中需要处理的&#xff0c;那么就在递归函数里加上这个参数&#xff0c; 并且…

运维锅总详解进程、内核线程、用户态线程和协程

I/O 密集型应用、计算密集型应用应该用什么实现&#xff1f;进程、内核线程、用户态线程、协程它们的原理和应用场景又是什么&#xff1f;如何组合它们才能让机器性能达到最优&#xff1f;它们的死锁和竞态又是什么&#xff1f;如何清晰地表示它们之间的关系&#xff1f;希望读…

创新设计策略:提升大屏幕可视化设计效果的关键方法

随着科技的不断发展和数据量的快速增长&#xff0c;数据可视化大屏在各个行业中的应用越来越广泛&#xff0c;可以帮助人们更好地理解和分析数据&#xff0c;可视化大屏设计也因此成了众多企业的需求。但很多设计师对可视化大屏设计并不了解&#xff0c;也不知道如何制作可视化…

一.9 重要主题

在此&#xff0c;小结一下我们旋风式的系统漫游。这次讨论得出一个很重要的观点&#xff0c;那就是系统不仅仅只是硬件。系统是硬件和系统软件互相交织的集合体。它们必须共同协作以达到运行应用程序的最终目的。本书的余下部分会讲述硬件和软件的详细内容&#xff0c;通过了解…

UnityHub 无法添加模块问题

文章目录 1.问题描述2.问题解决 1.问题描述 在Hub中无法添加模块 2.问题解决 1、点击设置 2、设置版本安装位置 可以发现installs的安装位置路径设置不是unity安装位置&#xff0c;这里我们更改成自己电脑unity安装位置的上一级路径 添加模块正常&#xff1a;

java链表常见简单面试算法题

头插法、尾插法 头插法&#xff1a;先待插入指向头结点的next&#xff0c;后头结点的next指向待插入。 尾插法&#xff1a;借助尾指针&#xff0c;直接插入 /*** 头插法* param head* return*/public static Node head_insert(Node head, int t){Node nodenew Node(t);node.set…