【阅读SpringMVC源码】手把手带你debug验证SpringMVC执行流程
✿ 阅读源码思路:
先跳过非重点,深入每个方法,进入的时候可以把整个可以理一下方法的执行步骤理一下,也可以,理到某一步,继续深入,回来后,接着理清除下面的步骤。
✿ 阅读本文的准备工作,预习一下SpringMVC的执行流程
■ 解释一下,为什么标题是验证SpringMVC执行流程:
不知道小伙伴有没有做过物理实验的验证实验,道理是一样的,举个高中生都做过的物理实验吧----自由落体实验,这个实验是通过小钢球做抛物运动,验证重力加速度的g值是9.8。对于本文,咱的做法是通过调试来验证SpringMVC的执行流程是:
1、前端控制器接收到客户端的请求后,通过处理器映射器handlerMappings,根据路径urlPath去匹配选择处理器handler,最终返回一个处理器执行链对象HandlerExcutionChain。
2、前端控制器通过处理器适配器,调用处理器的方法,然后处理器执行后返回模型视图对象给处理器适配器,适配器再将模型视图对象返回给前端对象。
3、前端控制器通过视图解析器,将模型视图进行解析,然后将模型数据填充到View,并渲染到视图,然后返回响应。
SpirngMVC执行流程图(图片来源于叩丁狼)

一、执行流程前的次要源码
● 开始debug的时候,对HttpMethod感到好奇,点进去查看一下HttpMethod究竟是何物?

- HttpMethod 是请求方法的枚举类,结合咱浏览器地址栏的参数是直接输入, - 可以知道咱的HttpMethod的值是Get
  
- 果然咱的HttpMethod的值是Get,所以下一步会执行super.service(request, response); 
- ctr进入该方法看一下,究竟是何物,发现按ctr没有反应【 - 解决:重新打开该类的文件】
  
- 进入super.service(request, response);内部一探究竟: 
- 发现这个service方法做的是请求分发操作,结合咱的请求方法是GET,所以下一步咱是到doGet方法去一探究竟~ 
  
- 再进入processRequest方法~ 
  
- 进入发现重点是doService(request, response);那咱就进入该方法内部一探究竟吧~ 
  
- 进入发现重点是doDispatch(request, response);那咱就进入该方法内部一探究竟吧~ 
  
二、真正的springMVC执行流程的源码分析
1、验证:前端控制器接收到客户端的请求后,通过处理器映射器handlerMappings,根据路径urlPath去匹配选择处理器handler,最终返回一个处理器执行链对象HandlerExcutionChain。
● 获取处理器映射器返回处理器执行链对象,getHandler(processedRequest);方法
【咱提前了解到的springMVC的执行过程:前端控制器接收请求,通过处理器映射器寻找处理器,返回一个处理器执行链对象】。

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

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

● 进入返回处理器对象的getHandlerInternal方法内部:Object handler = lookupHandler(lookupPath, request);
【咱提前了解到的springMVC的执行过程:前端控制器接收请求,通过处理器映射器依据路径进行匹配来寻找处理器,返回一个处理器执行链对象】。

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


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

......
✿ 至此,验证了SpringMVC的执行流程:前端控制器接收到客户端的请求后,通过处理器映射器handlerMappings,根据路径urlPath去匹配选择处理器handler,最终返回一个处理器执行链对象HandlerExcutionChain。
2、验证:前端控制器通过处理器适配器,调用处理器的方法,然后处理器执行后返回模型视图对象给处理器适配器,适配器再将模型视图对象返回给前端对象.
● 获取处理器适配器对象HandlerAdapter

● 进入getHandlerAdapter获取处理器适配器方法内部:
看到了this.handlerAdapters 处理器映射器-观察它的值为:
[org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@60038152]

- 非重点:判断与“被修改”相关的
- 非重点:前置拦截器相关的
  
● 进入ha.handle方法内部观察:

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


- `执行完((Controller) handler).handleRequest(request, response);即调用咱自己书写的处理器类的方法~`` 
- 返回, - 继续观察,发现ModelAndView对象,观察它的值:
 ModelAndView [view="/WEB-INF/views/welcome.jsp"; model={msg=你好,easyMVC}]
  
- 这个深入进去,设置视图名称 
  
- 非重点:后置拦截器 
  
- 继续观察---观察到:处理分发的结果,深入进去观察: 
  
- 非重点:错误异常相关的 
- 重点:渲染方法 
  
。。。。。。跟视图有关的重点。。。。。
至此,验证了SpringMVC的执行流程:前端控制器通过处理器适配器HandlerAdapter,调用处理器HelloController的方法,然后处理器执行后返回模型视图对象ModelAndView给处理器适配器,适配器再将模型视图对象返回给前端控制器.
3、验证:前端控制器通过视图解析器,将模型视图进行解析,然后将模型数据填充到View,并渲染到视图,然后返回响应.
- 非重点:国际化
- 非重点:视图名称
  
● 重点:渲染视图


- 观察到返回一个模型对象,根据方法调用的先后顺序,先调用了view.render(mv.getModelInternal(), request, response);的mv.getModelInternal()方法,需要重新深入一次
  
  
● 在渲染视图render方法内部,观察到mergedModel,观察它的值:
{msg=你好,easyMVC}

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

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

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

至此,验证:前端控制器通过视图解析器,将模型视图进行解析,然后将模型数据填充到View,并渲染到视图,然后返回响应.
【阅读SpringMVC源码】手把手带你debug验证SpringMVC执行流程的更多相关文章
- SpringMVC源码分析(3)DispatcherServlet的请求处理流程
		<springmvc源码分析(2)dispatcherservlet的初始化>初始化DispatcherServlet的多个组件. 本文继续分析DispatcherServlet解析请求的 ... 
- SpringMVC源码剖析(三)- DispatcherServlet的初始化流程
		在我们第一次学Servlet编程,学Java Web的时候,还没有那么多框架.我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根据需要重写一下doGet,doPost方法,跳转 ... 
- springmvc 源码分析(二)-- DiapartcherServlet核心调用流程分析
		测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git 项目结构代码如下: 一: cont ... 
- spark 源码分析之二十一 -- Task的执行流程
		引言 在上两篇文章 spark 源码分析之十九 -- DAG的生成和Stage的划分 和 spark 源码分析之二十 -- Stage的提交 中剖析了Spark的DAG的生成,Stage的划分以及St ... 
- SpringMVC源码分析系列
		说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时sp ... 
- SpringMVC源码
		SpringMVC源码分析系列 说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Serv ... 
- 【Spring专场】「IOC容器」不看源码就带你认识核心流程以及运作原理
		这是史上最全面的Spring的核心流程以及运作原理的分析指南 [Spring核心专题]「IOC容器篇」不看繁琐的源码就带你浏览Spring的核心流程以及运作原理 [Spring核心专题]「AOP容器篇 ... 
- SpringMVC源码情操陶冶-FreeMarker之web配置
		前言:本文不讲解FreeMarkerView视图的相关配置,其配置基本由FreeMarkerViewResolver实现,具体可参考>>>SpringMVC源码情操陶冶-ViewRe ... 
- 手把手带你阅读Mybatis源码(三)缓存篇
		前言 大家好,这一篇文章是MyBatis系列的最后一篇文章,前面两篇文章:手把手带你阅读Mybatis源码(一)构造篇 和 手把手带你阅读Mybatis源码(二)执行篇,主要说明了MyBatis是如何 ... 
随机推荐
- python基础详解
			python基础部分 python基础一 python基础二 Python最详细,最深入的代码块小数据池剖析 深浅copy python文件操作 python函数部分 python函数初识 pytho ... 
- Vue之 watch、computed、filter之间的区别与使用场景
			computed 计算属性: 当页面中需要使用大量的表达式处理数据时,为了页面维护更加简单,所以使用 计算属性 来出来复杂的逻辑运算 watch 侦听器 当需要在数据变化时执行异步或开销较大的操作时 ... 
- django之定义统一返回数据格式与GET/POST装饰器
			1. 为了返回给网页前端的格式统一,定义一个通用的插件类,返回统一格式数据 # enconding:utf-8 """ 定义一个插件类, ""&quo ... 
- Loadrunner11录制移动端测试脚本(原文:http://blog.csdn.net/zhailihua/article/details/73610317)
			一.LR配置 1)LR设置代理,利用手机录制脚本 1-协议选择Web(HTTP/HTML)协议即可 2-录制开始前,对Recoding Options中的Port Mapping配置如下 a.新建Ne ... 
- AI算法测评(二)--算法测试流程
			根据算法测试过程中遇到的一些问题和管理规范, 梳理出算法测试工作需要关注的一些点: 编号 名称 描述信息 备注 1 明确算法测试需求 明确测试目的 明确测试需求, 确认测试需要的数据及场景 明确算法服 ... 
- HTML页元素自适应+居中总结(不定期补充)
			感谢大佬:https://www.cnblogs.com/SallyShan/p/11480685.html 图片自适应 背景图片自适应 /*背景页*/ #page_content{ width: 1 ... 
- Visual Studio 下error C2471: 无法更新程序数据库
			转载请注明来源:https://www.cnblogs.com/hookjc/ 解决方案:修改项目属性 右击项目 --> "属性" 1. "C/C++" ... 
- ReactiveCocoa 学习资料
			之前就有听说,感觉很强大,ReactiveCocoa更加被Mattt Thompson大神称为开启一个新Objective-C纪元.所以觉得非常有学习的必要了. 一些很好的学习资料: Reactive ... 
- 实现“手机qq”侧滑菜单 -- 吴欧
			基本数据采集 经过体验,手机QQ采用的应该是线性动画,即视图缩放比例等随手指在屏幕上滑动的距离以一次方程的形式变化. 提取基本数据,向右侧滑达到最大幅度时: 1. 右侧主视图左边界距离屏幕左边界的 ... 
- Kubectl —— 基本命令
			Kubectl -- 基本命令 1.kubectl 基本命令 2.项目的生命周期 3.声明式管理方法 service的类型: ClusterIP:提供一个集群内部的虚拟IP以供Pod访问( servi ... 
