SpringMVC 执行流程详解

news2024/11/24 15:20:45

目录

  • 前言
  • 1. SpringMVC 的核心组件概述
    • 1.1 DispatcherServlet
    • 1.2 HandlerMapping
    • 1.3 HandlerAdapter
    • 1.4 拦截器(HandlerInterceptor)
    • 1.5 ViewResolver
  • 2. SpringMVC 的执行流程详解
    • 2.1 接收请求并分发
    • 2.2 获取 HandlerExecutionChain
    • 2.3 获取 HandlerAdapter
    • 2.4 执行拦截器的 preHandle 方法
    • 2.5 调用处理器方法(HandlerMethod)
    • 2.6 执行拦截器的 postHandle 方法
    • 2.7 异常处理(全局异常处理器)
    • 2.8 解析视图
    • 2.9 渲染视图并响应客户端
    • 2.10 执行拦截器的 afterCompletion 方法
  • 3. SpringMVC 执行流程的整体架构
  • 结语

前言

SpringMVC 是 Java Web 开发中广泛应用的 MVC 框架,它以其高效、灵活的设计受到了开发者的青睐。在 SpringMVC 中,从接收到请求到最终给浏览器返回响应,涉及多个核心组件和步骤,每个环节都体现了框架的设计思想和高内聚低耦合的原则。本文将详细解析 SpringMVC 的执行流程,帮助读者全面了解其工作原理,为实际开发和问题排查提供理论支持。

1. SpringMVC 的核心组件概述

在深入了解执行流程之前,有必要先简单介绍几个核心组件:
在这里插入图片描述

1.1 DispatcherServlet

DispatcherServlet 是 SpringMVC 的核心调度器,负责接收 HTTP 请求并调度到相应的处理器。它相当于整个框架的中枢神经,将请求处理的每个环节串联起来。所有的请求都会先到达 DispatcherServlet

1.2 HandlerMapping

HandlerMapping 的职责是将请求 URL 映射到对应的处理器(Handler)。在 SpringMVC 中,处理器通常是一个注解标注的控制器方法(如 @RequestMapping 标注的方法)。

1.3 HandlerAdapter

HandlerAdapter 是对处理器的包装和适配器模式的应用。它负责调用具体的处理器方法并将结果返回。

1.4 拦截器(HandlerInterceptor)

拦截器是 SpringMVC 提供的一种扩展机制,用于在请求处理的不同阶段执行额外的逻辑。它包括 preHandle(请求处理前)、postHandle(请求处理后但视图渲染前)和 afterCompletion(请求完成后)三个方法。

1.5 ViewResolver

ViewResolver 是视图解析器,负责将处理器方法返回的逻辑视图名解析为实际的视图对象(如 JSP、Thymeleaf 模板等),并最终渲染视图。

2. SpringMVC 的执行流程详解

接下来,我们从请求到响应的整个流程,逐步剖析 SpringMVC 的执行机制。
在这里插入图片描述

2.1 接收请求并分发

当客户端发出 HTTP 请求时,DispatcherServlet 是第一个接收到请求的组件。在初始化阶段,DispatcherServlet 已经加载了 HandlerMappingHandlerAdapter 等必要组件,并完成了相关配置。当请求到达时,它会先解析请求路径和方法类型(如 GET、POST),以便后续的处理。

@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 核心调度逻辑
    HandlerExecutionChain mappedHandler = getHandler(request);
    if (mappedHandler == null) {
        noHandlerFound(request, response);
        return;
    }
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    ...
}

2.2 获取 HandlerExecutionChain

DispatcherServlet 通过调用 HandlerMapping 来找到对应的处理器,并生成一个 HandlerExecutionChain 对象。这个对象不仅包含了处理器本身,还包括相关的拦截器链。HandlerMapping 会根据配置的规则(如注解映射、URL 配置等)来寻找处理器。

常见的 HandlerMapping 实现

  • RequestMappingHandlerMapping:处理基于注解的映射规则。
  • SimpleUrlHandlerMapping:用于传统的配置方式。

2.3 获取 HandlerAdapter

找到处理器后,DispatcherServlet 会通过 HandlerAdapter 调用处理器的具体方法。HandlerAdapter 充当适配器的角色,使得不同类型的处理器(如注解控制器、接口实现)都能统一被调用。

HandlerAdapter 的作用

HandlerAdapter 将处理器的逻辑抽象化,使框架可以灵活扩展。开发者在实现自定义处理器时,可以通过实现对应的 HandlerAdapter 来适配新的处理逻辑。
在这里插入图片描述

2.4 执行拦截器的 preHandle 方法

在调用处理器方法之前,DispatcherServlet 会执行所有拦截器的 preHandle 方法。如果某个拦截器返回 false,请求会被中止,并不会执行后续的处理器方法。

拦截器的典型应用场景包括:

  • 用户身份认证
  • 权限检查
  • 请求参数预处理

2.5 调用处理器方法(HandlerMethod)

HandlerAdapter 调用处理器方法时,会自动注入参数(如请求参数、路径变量、表单数据等),并接收返回值。处理器方法的返回值可以是多种类型,例如:

  • 字符串(视图名称)
  • JSON 数据(配合 @ResponseBody@RestController 使用)
  • 自定义对象

此阶段的核心任务是处理业务逻辑,并将结果封装起来。

2.6 执行拦截器的 postHandle 方法

处理器方法执行完毕后,拦截器的 postHandle 方法会被调用。此时,控制器方法的结果已经生成,但视图还未渲染。postHandle 常用于修改模型数据或进行日志记录。

2.7 异常处理(全局异常处理器)

如果在请求处理过程中抛出异常,SpringMVC 会触发异常处理机制。全局异常处理器(如 @ControllerAdvice 中定义的 @ExceptionHandler)可以捕获并处理这些异常,从而返回友好的错误信息。

异常处理机制

  • 优先匹配 @ExceptionHandler 注解的方法。
  • 如果未找到,调用全局异常解析器(HandlerExceptionResolver)。

2.8 解析视图

处理器方法返回视图名称后,DispatcherServlet 会调用 ViewResolver 将逻辑视图名解析为具体的视图对象。视图解析器的典型实现包括:

  • InternalResourceViewResolver:解析 JSP 文件路径。
  • ThymeleafViewResolver:支持 Thymeleaf 模板引擎。

2.9 渲染视图并响应客户端

视图解析完成后,SpringMVC 会将模型数据填充到视图中,并将最终渲染的内容写入 HTTP 响应。对于 JSON 数据,通常通过 MappingJackson2HttpMessageConverter 等消息转换器直接写入。

2.10 执行拦截器的 afterCompletion 方法

最后,拦截器的 afterCompletion 方法会在视图渲染完成后执行。这一阶段适合用于资源清理或记录最终的处理状态。

3. SpringMVC 执行流程的整体架构

通过上面的分析,我们可以总结出 SpringMVC 的执行流程图:

  1. 客户端发出请求 -> DispatcherServlet 接收
  2. 寻找处理器(Handler) -> 执行拦截器
  3. 调用处理器方法 -> 返回结果
  4. 异常处理(若有) -> 解析视图 -> 渲染视图
  5. 执行拦截器的完成方法 -> 响应客户端

结语

SpringMVC 的执行流程清晰而高效,其设计充分体现了开闭原则和职责分离的思想。从接收请求到响应结果,多个组件紧密配合,同时提供了丰富的扩展点,允许开发者根据需求自定义功能。理解这些流程不仅有助于开发高质量的 Web 应用,还能更快速地定位和解决问题。

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

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

相关文章

安卓应用安装过程学习

声明:此文章来自http://shuwoom.com/?p60的学习记录 启动式安装 public static final IPackageManager main(Context context, Installer installer,boolean factoryTest, boolean onlyCore) {PackageManagerService m new PackageManagerService(context, inst…

如何通过OpenSSL来创建自签名的CA证书?

通过创建自签名CA证书可以让我们在没有商业支持的情况下学习与研究PKI(公钥基础设施)和SSL/TLS技术,本文将详细介绍如何通过OpenSSL来创建自签名的CA证书。 1. 初衷:为什么需要创建自签名CA证书? 除了开篇引言中提到的…

mac安装Pytest、Allure、brew

安装环境 安装pytest 命令 pip3 install pytest 安装allure 命令:brew install allure 好吧 那我们在安装allure之前 我们先安装brew 安装brew 去了官网复制了命令 还是无法下载 如果你们也和我一样可以用这个方法哦 使用国内的代码仓库来执行brew的安装脚本…

Python中“暂停”(time.sleep?input?)

input函数最是经典,在多种实现中简单粗暴单纯而经济。 (笔记模板由python脚本于2024年11月22日 10:58:38创建,本篇笔记适合比较熟悉python的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大…

刷题——【模板】二维前缀和

前缀和 题目题目链接题解方法一方法二 题目 描述 给你一个 n 行 m 列的矩阵 A ,下标从1开始。 接下来有 q 次查询,每次查询输入 4 个参数 x1 , y1 , x2 , y2 请输出以 (x1, y1) 为左上角 , (x2,y2) 为右下角的子矩阵的和, 输入描述&#x…

10 - Clickhouse集群部署以及副本和分片

目 一、副本 1、简介 2、副本写入流程 3、副本配置步骤 3.1、启动zookeeper集群 3.2、在 hallo100 的/etc/clickhouse-server/config.d 目录下创建一个名为metrika.xml 的配置文件,内容如下: 3.3、在 hallo100 的/etc/clickhouse-server/config.xml 中增加如…

Ubuntu24.04LTS设置root用户可远程登录

Ubuntu24.04LTS设置root用户可远程登录 文章目录 Ubuntu24.04LTS设置root用户可远程登录1. 设置root密码2. 设置root用户可远程登录1. 查看ssh服务是否安装2. 安装ssh服务3. 再次查看ssh服务是否安装4. 配置ssh文件5. 重启ssh服务6. root远程登录 1. 设置root密码 Ubuntu安装后…

DMA理论篇

DMA理论篇 简介 传统的数据传输都是需要CPU来实现,从一个地方拷贝到另一个地方;而DMA(Direct Memory Access)则不完全依赖CPU,DMA更新芯片SOC的一个控制器,他可以控制数据从内存中传输到另一个地方(外设、soc其它模块)&#xff…

理解原子变量之三:原子性与memory_order_relaxed

目录 CPU与内存的关系 原子性 典型使用场景 在本系列的第一篇文章理解原子变量之一:从互斥锁到原子变量,最粗浅的认识_原子互斥-CSDN博客,我通过几个实例从感性认识的角度介绍了原子性。本文在第一篇文章的基础上,从理性认识的…

医院信息化与智能化系统(22)

医院信息化与智能化系统(22) 这里只描述对应过程,和可能遇到的问题及解决办法以及对应的参考链接,并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图,可以试试PlantUML,告诉GPT你的文件结构,让他给你对应…

青少年编程等级考试C++一级,硬币反转问题

代码 #include<iostream>using namespace std;bool a[300];int main(){ int n,m; cin >> n >> m; for(int i 1;i < m;i) { for (int j 1;j < n;j) { if( j % i 0) { a[j] !a[j];…

数字化工厂 MES试点方案全解析(二)

生产过程监控与数据采集 在生产线上部署各类传感器、数据采集终端等设备&#xff0c;与 MES 系统相连&#xff0c;实时采集生产数据&#xff0c;如设备运行参数&#xff08;温度、压力、转速等&#xff09;、产品加工数据&#xff08;尺寸、重量、加工时间等&#xff09;、物料…

动态规划子数组系列一>最长湍流子数组

1.题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int maxTurbulenceSize(int[] arr) {int n arr.length;int[] f new int[n];int[] g new int[n];for(int i 0; i < n; i)f[i] g[i] 1;int ret 1;for(int i 1; i < n-1; i,m. l.kmddsfsdafsd){int…

(十一)Python字符串常用操作

一、访问字符串值 Python访问子字符串变量&#xff0c;可以使用方括号来截取字符串。与列表的索引一样&#xff0c;字符串索引从0开始。 hh"LaoTie 666" hh[2] mm"床前明月光" mm[3] 字符串的索引值可以为负值。若索引值为负数&#xff0c;则表示由字符…

Sigrity SPEED2000 DDR simulation模式如何生成和解读DDR仿真报告-SODIMM-Write模式

Sigrity SPEED2000 DDR simulation模式如何生成和解读DDR仿真报告-SODIMM-Write模式 Sigrity SPEED2000 DDR simulation模式如何进行DDR仿真分析操作指导-SODIMM-Write模式详细介绍了如何进行DDR Write模式的仿真分析,下面基于此仿真结果进行DDR报告的输出和解读分析 在workfl…

【图像检测】深度学习与传统算法的区别(识别逻辑、学习能力、泛化能力)

识别逻辑 深度学习 使用了端到端的学习策略&#xff0c;直接学习从图像到检测结果的映射关系&#xff0c;自动提取特征&#xff0c;并且根据特征与特征之间的关系&#xff0c;计算出检测结果。 传统算法 则是人工提取特征&#xff0c;比如边缘特征&#xff0c;直线特征&#x…

TypeScript 系统学习 章节3

想学习 TypeScript 的小伙伴看过来&#xff0c;本文将带你一步步学习 TypeScript 入门相关的十四个知识点&#xff0c;详细的内容大纲请看下图&#xff1a; 一、TypeScript 是什么 TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集&#xff0c…

opencv undefined reference to `cv::noarray()‘ 。window系统配置opencv,找到opencv库,但连接不了

之前都是在ubuntu里用opencv&#xff0c;今天为了方便在平时用Window10系统也用下c版的cv&#xff0c;就想配置一下vscode的cv环境&#xff0c;直接下载了一个编译好的opencv库&#xff08;带build文件夹的&#xff09;&#xff0c;刚开始用的是visual studio的编译器&#xff…

利用FileZilla搭建ftp服务器

一 利用windows自带的ftp服务搭建服务器&#xff0c;要复杂一些&#xff0c;好处是无需借用外部软件。 也有一些好的工具&#xff0c;如FileZilla的Server版&#xff0c;构建过程简单&#xff0c;好用。 下面看看。 二 安装FileZilla Server 当前下载版本是0.9.43&#xf…

【刷题21】BFS解决FloodFill算法专题

目录 一、图像渲染二、岛屿数量三、岛屿的最大面积四、被环绕的区域 一、图像渲染 题目&#xff1a; 思路&#xff1a; 如果起始位置的颜色(数值)与color相同&#xff0c;直接返回该数组上下左右一层一层的找与当前位置颜色相同的&#xff0c;并且该位置不越界&#xff0c;然…