【阅读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是如何 ...
随机推荐
- IntelliJ IDEA 中文官方文档
目录 认识IntelliJ IDEA IntelliJ IDEA 安装和设置 IntelliJ IDEA如何使用 IntelliJ IDEA中不容错过的快捷键 IntelliJ IDEA专业的使用技巧 ...
- kicad6 封装库的管理
kicad6 封装库的管理 kicad6 的封装编辑器有很多莫名其妙的地方, 让人在第一次用的时候摸不着头脑. 在下面稍微总结一下封装库的操作 1. 封装库的创建 选择 文件 -> 新建库 有两 ...
- AT2699 [ARC081D] Flip and Rectangles
以下是简要题解: 首先思考如何判定一个矩形是否能通过操作变成全黑. 首先从简单而又特殊的 \(2 \times 2\) 的矩形开始,不难发现只要其中黑色数量不为奇数即可. 近一步拓展可以发现,一个矩形 ...
- G1垃圾收集器
G1(Garbage-First) G1是一种服务端应用使用的垃圾收集器,目标是用在多核.大内存的机器上,它在大多数情况下可以实现指定的GC暂停时间,同时还能保持较高的吞吐量. 特点 压缩空闲空间不会 ...
- 微信、QQ添加Universal Link
官方说明 1. Universal Links是什么 Universal Links(通用链接),是苹果在iOS9之后,提供的一种"可通过传统HTTP链接来跳转APP"的能力. 该 ...
- C字符串倒置-中部对称
问题如图 Code #include<stdio.h> #include<string.h> #define MAX_LENGTH 10//最大字符串长度 void inver ...
- ArrayList和LinkList的区别
底层实现区别 ArrayList 底层实现就是数组,且ArrayList实现了RandomAccess,表示它能快速随机访问存储的元素,通过下标 index 访问,只是我们需要用 get() 方法的形 ...
- svn使用规范、在Windows下使用svn命令行工具、svn命令行的解释
以前在公司一直使用git,现在公司有用svn,一时间还真的不知道如何下手,在网上搜寻了很多大神和官网文档的指导,总结了下面一份教程,希望能够帮助大家快速上手,如果想更细致的了解相关内容,可以点击每个小 ...
- 以鶸ice为例,手撸一个解释器(一)明确目标
代码地址 # HelloWorld.ice print("hello, world") 前言(废话) 其实从开始学习编译原理到现在已经有快半年的时间了,但是其间常常不能坚持看下去龙 ...
- Solution -「UVA 1104」Chips Challenge
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的方格图中,有一些格子已经放了零件,有一些格子可以放零件,其余格子不能放零件.求至多放多少个 ...