【阅读SpringMVC源码】手把手带你debug验证SpringMVC执行流程

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475

✿ 阅读源码思路:

先跳过非重点,深入每个方法,进入的时候可以把整个可以理一下方法的执行步骤理一下,也可以,理到某一步,继续深入,回来后,接着理清除下面的步骤。

✿ 阅读本文的准备工作,预习一下SpringMVC的执行流程

■ 解释一下,为什么标题是验证SpringMVC执行流程:

不知道小伙伴有没有做过物理实验的验证实验,道理是一样的,举个高中生都做过的物理实验吧----自由落体实验,这个实验是通过小钢球做抛物运动,验证重力加速度的g值是9.8。对于本文,咱的做法是通过调试来验证SpringMVC的执行流程是:

1、前端控制器接收到客户端的请求后,通过处理器映射器handlerMappings,根据路径urlPath去匹配选择处理器handler,最终返回一个处理器执行链对象HandlerExcutionChain。

2、前端控制器通过处理器适配器,调用处理器的方法,然后处理器执行后返回模型视图对象给处理器适配器,适配器再将模型视图对象返回给前端对象。

3、前端控制器通过视图解析器,将模型视图进行解析,然后将模型数据填充到View,并渲染到视图,然后返回响应。

🏓 SpirngMVC执行流程图(图片来源于叩丁狼)

image

一、执行流程前的次要源码

● 开始debug的时候,对HttpMethod感到好奇,点进去查看一下HttpMethod究竟是何物?

image

  • HttpMethod 是请求方法的枚举类,结合咱浏览器地址栏的参数是直接输入,可以知道咱的HttpMethod的值是Get
    image
  • 果然咱的HttpMethod的值是Get,所以下一步会执行super.service(request, response);
  • ctr进入该方法看一下,究竟是何物,发现按ctr没有反应解决:重新打开该类的文件
    image
  • 进入super.service(request, response);内部一探究竟:
  • 发现这个service方法做的是请求分发操作,结合咱的请求方法是GET,所以下一步咱是到doGet方法去一探究竟~
    image
  • 再进入processRequest方法~
    image
  • 进入发现**重点是doService(request, response);**那咱就进入该方法内部一探究竟吧~
    image
  • 进入发现**重点是doDispatch(request, response);**那咱就进入该方法内部一探究竟吧~
    image

二、真正的springMVC执行流程的源码分析

1、验证:前端控制器接收到客户端的请求后,通过处理器映射器handlerMappings,根据路径urlPath去匹配选择处理器handler,最终返回一个处理器执行链对象HandlerExcutionChain。

● 获取处理器映射器返回处理器执行链对象,getHandler(processedRequest);方法

【咱提前了解到的springMVC的执行过程:前端控制器接收请求,通过处理器映射器寻找处理器,返回一个处理器执行链对象】。

image

● 发现了 this.handlerMappings 处理器映射器-观察它的值为:

[org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping@40851021]【咱提前了解到的springMVC的执行过程:前端控制器接收请求,通过处理器映射器寻找处理器,返回一个处理器执行链对象】。
image

● 进入 mapping.getHandler(request); 方法内部:

image

● 进入返回处理器对象的getHandlerInternal方法内部:Object handler = lookupHandler(lookupPath, request);

【咱提前了解到的springMVC的执行过程:前端控制器接收请求,通过处理器映射器依据路径进行匹配来寻找处理器,返回一个处理器执行链对象】。
image

● 进入lookupHandler方法内部:验证了通过处理器映射器依据路径进行匹配来寻找处理器。还观察到urlPath的值,正是咱配置的处理器的路径

image
image

---- 按照阅读源码观察步骤,到这一步,你已经理清楚了,可以调试回去,回去到:

image

✿ 至此,验证了SpringMVC的执行流程:前端控制器接收到客户端的请求后,通过处理器映射器handlerMappings,根据路径urlPath去匹配选择处理器handler,最终返回一个处理器执行链对象HandlerExcutionChain。


2、验证:前端控制器通过处理器适配器,调用处理器的方法,然后处理器执行后返回模型视图对象给处理器适配器,适配器再将模型视图对象返回给前端对象.

● 获取处理器适配器对象HandlerAdapter

image

● 进入getHandlerAdapter获取处理器适配器方法内部:

看到了this.handlerAdapters 处理器映射器-观察它的值为:
[org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@60038152]
image

  • 非重点:判断与“被修改”相关的
  • 非重点:前置拦截器相关的
    image

● 进入ha.handle方法内部观察:

image

  • 看到了(Controller) handler -观察它的值为:
    com.shan.hello.HelloController@591b274

image

image

  • `执行完((Controller) handler).handleRequest(request, response);即调用咱自己书写的处理器类的方法~``
  • 返回,继续观察,发现ModelAndView对象,观察它的值
    ModelAndView [view="/WEB-INF/views/welcome.jsp"; model={msg=你好,easyMVC}]
    image
  • 这个深入进去,设置视图名称
    image
  • 非重点:后置拦截器
    image
  • 继续观察—观察到:处理分发的结果,深入进去观察:
    image
  • 非重点:错误异常相关的
  • 重点:渲染方法
    image

。。。。。。跟视图有关的重点。。。。。

至此,验证了SpringMVC的执行流程:前端控制器通过处理器适配器HandlerAdapter,调用处理器HelloController的方法,然后处理器执行后返回模型视图对象ModelAndView给处理器适配器,适配器再将模型视图对象返回给前端控制器.


3、验证:前端控制器通过视图解析器,将模型视图进行解析,然后将模型数据填充到View,并渲染到视图,然后返回响应.

  • 非重点:国际化
  • 非重点:视图名称
    image

● 重点:渲染视图

image
image

  • 观察到返回一个模型对象,根据方法调用的先后顺序,先调用了view.render(mv.getModelInternal(), request, response);的mv.getModelInternal()方法,需要重新深入一次
    image
    image

● 在渲染视图render方法内部,观察到mergedModel,观察它的值:

{msg=你好,easyMVC}
image

  • 非重点:预响应

● 重点:renderMergedOutputModel【符合咱提前了解的SpringMVC的执行流程中渲染视图的数据】

image

● 深入,发现是将共享数据设置到请求中去

image

● 接着往下,跳过非重点,来到请求转发

image

至此,验证:前端控制器通过视图解析器,将模型视图进行解析,然后将模型数据填充到View,并渲染到视图,然后返回响应.

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

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

相关文章

Zabbix监控(十六):分布式监控-Zabbix Proxy

说明:Zabbix支持分布式监控,利用Proxy代理功能,在其他网络环境中部署代理服务器,将监控数据汇总到Zabbix主服务器,实现多网络的分布式监控,集中监控。1、分布式监控原理Zabbix proxy和Zabbix server一样&am…

CC254x--BLE

BLE协议栈 BLE体系结构,着重了解GAP和GATT。 PHY物理层在2.4GHz的ISM频段中跳频识别。LL连接层:控制设备的状态。设备可能有5中状态:就绪standby,广播advertising,搜索scanning,初始化initiating和连接con…

DW 在onload运行recordset find.html时 发生了以下javascript错误

这两天打开Dreamweaver CS5,总是弹出一个错误,写着: 在onLoad运行RecordsetFind.htm时,发生了以下JavaScript错误: 在文件“RecordsetFind”中: findRsisnotdefined 在关闭Dreamweaver的时候也会弹出一个类…

Azure Container App(一)应用介绍

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 一,引言 容器技术正日益成为打包、部署应用程序的第一选择。Azure 提供了许多使用容器的选项。例如&#xff0…

CC254x--API

CC2541常用API 连接 定义广播数据 GAPRole_SetParameter(GAPROLE_ADVERT_DATA,…); 自定义扫描响应数据 GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA,…); 密码管理回调 ProcessPasscodeCB(); 状态管理回调 peripheralStateNotificationCB(); 通信控制 添加GATT服务 GATTServ…

mysql 分区信息查看

select partition_name part,partition_expression expr,partition_description descr,table_rows from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMASCHEMA() AND TABLE_NAMEmx_domain//查看分区信息 CREATE TABLE mx_domain (id int(10) NOT NULL AUTO_INCREMENT,name…

怎样配置键盘最方便,以及一些设计的思考

使用Emacs的人,如果肯折腾,肯定有重新映射键盘的经历。我原来经常看到的是把Ctrl和Capslock交换,但是我感觉没什么道理,因为Ctrl已经用的很熟练了,换了反而不方便,而且对其他程序影响太大。那么我们就要使用…

profile、服务、特征、属性之间的关系

一个profile有很多的服务,一个服务又有很多的特性,一个特性中又有几种属性条目组成。 profile(数据配置文件) 一个profile文件可以包含一个或者多个服务,一个profile文件包含需要的服务的信息或者为对等设备如何交互的…

面试突击32:为什么创建线程池一定要用ThreadPoolExecutor?

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 在 Java 语言中,并发编程都是依靠线程池完成的,而线程池的创建方式又有很多,但从大的分类…

Bootstrap datepicker 在弹出窗体modal中不工作

解决办法 在 show 方法后面 添加 下面一段代码 $(#modalCard).modal(show);—例子 打开 弹出窗体 //$(#modalCard).modal(hide); $(#modalCard).on(shown.bs.modal, function () { //$(.input-group.date).datetimepicker({ $(#dpReceiveDate).datetimepicker({ format: "…

学习Samba基础命令详解之大话西游01

服务名:smb配置目录:/etc/sabma/主配置文件:/etc/sabma/smb.conf# Global Settings 17行workgroup语法 workgtoup <工作组群>; 预设 workgroup MYGROUP 说明 设定 Samba Server 的工作组 例 workgroup workgroup 和WIN2000S设为一个组&#xff0c;可在网上邻居可中看到…

实例讲解getopt()函数的使用

[cpp] view plaincopy #include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { extern char *optarg;//保存选项的参数 extern int optind, opterr, optopt; int ch; printf("\n\n"); pri…

机器学习实战 | SKLearn最全应用指南

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 作者&#xff1a;韩信子ShowMeAI 教程地址&#xff1a;http://www.showmeai.tech/tutorials/41 本文地址&#xff1a;http…

windows 64位 安装mvn提示 不是内部或外部命令

在安装mvn的过程中当在mvn的目录下去执行mvn命令的时候是可以正常执行的&#xff0c;当设置好环境变量后执行后发现提示mvn不是内部命令。 原因是设置的MAVEN_HOME变量未被Path解析&#xff0c;解决办法是 直接把path中的%MAVEN_HOME%\bin 换成MAVEN_HOME的绝对路径&#xff0c…

Scheme语言入门

2019独角兽企业重金招聘Python工程师标准>>> Scheme语言入门 最早听说 LISP&#xff0c;是 Stallman 的 GNU Emacs 中将 LISP 作为嵌入语言&#xff0c;定制和增强 Emacs。GNU Emacs 是一个文本编辑器&#xff0c;文本就是一种符号&#xff0c;而 Lisp 正好就是针对…

题目四 艺术品

Dr.Kong设计了一件艺术品&#xff0c;该艺术品由N个构件堆叠而成&#xff0c;N个构件从高到低按层编号依次为1&#xff0c;2&#xff0c;……,N。艺术品展出后&#xff0c;引起了强烈的反映。Dr.Kong观察到&#xff0c;人们尤其对作品的高端部分评价甚多。 狂热的Dr.Kong一激动…

如何将docker 镜像上传到docker hub仓库

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 如何将docker 镜像上传到docker hub仓库 目录* 如何将docker 镜像上传到docker hub仓库 背景 1.注册docker hub账号 2.…

C# 类(14) 事件

using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace ConsoleApplication1 {//先在外面定义一个类.class MyClass{//委托是事件的前提,所以先定义一个委托public delegate void Mydelagate(int i);// 接着定义事件. public event…

ThinkPHP框架 _ 学习3

【路由解析】 通过url地址get参数找到指定的控制器&#xff0c;并进行对应方法调用请求 http://网址/index.php?m模块名称&c控制器&a方法 以上url地址信息代码不够优雅、不安全。 tp框架url地址可以由以下四种 http://网址/index.php?mXX&cXX&aXX 基本get模…

The slave I/O thread stops(equal MySQL server ids)

在学习replication时遇到了如下问题&#xff1a;显然看到Slave_IO_Running 为NO 表示有问题&#xff1b;到日志里查看&#xff0c;错误如下&#xff1a;position 98100121 17:09:03 [ERROR] The slave I/O thread stops because master and slave have equal MySQL server ids;…