SpringMVC执行流程
1.SpringMVC执行流程分析图
例子
(1)创建 HaloHandler package com.li.web.debug; import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; /** * @author 李 * @version 1.0 */@Controllerpublic class HaloHandler { //编写方法,响应请求,返回一个 ModelAndView对象 @RequestMapping(value = "/debug/springmvc") public ModelAndView halo(HttpServletRequest request, HttpServletResponse response) { ModelAndView modelAndView = new ModelAndView(); //对应到 WEB-INF/pages/ok.jsp (ok的前后缀是你在视图解析器中配置的前后缀) modelAndView.setViewName("ok"); //在model中放入数据 k-v,ModelAndView的属性也会被springmvc放入到request域中 modelAndView.addObject("name", "齐天大圣"); return modelAndView; }}
(2)创建ok.jsp,作为响应后跳转的页面 <%@ page contentType="text/html;charset=UTF-8" language="java" %> ok进入到ok页面
name-${requestScope.name}
2.源码debug
我们以上述代码为例子进行源码分析。
(1)在 DispatcherServlet 的 doService 方法中打上断点,在浏览器中访问目标方法,可以看到光标跳转到断点处:当请求发送到服务器时,tomcat 将 http 请求包装成 request 对象,前端控制器 DispatcherServlet 使用 doService() 方法接收这个 request 对象。
(2)点击 step over 前进,可以看到这里的 getWebApplicationContext() 就是 spring 容器对象。也就是说,当接收到url请求的时候,前端控制器就会进行spring 容器的初始化,将各种 bean 放入到容器中。
(3)点击 step over,在经过一系列处理之后调用了 doDispatch() 方法。这是一个核心的方法。
(4)点击 step into,进入 doDispatch() 方法,该方法中首先定义了一个处理器执行链,它用于存放拦截器(多个)和目标 Handler。然后定义了ModelAndView 对象,用于存放视图信息和数据。
执行下面的语句后,就通过映射拿到了处理器执行链 HandlerExecutionChain 的目标 Handler 和拦截器链
(5)点击 step over,跳到如下:获取适配器,包含要执行的目标 Handler
(6)点击 step over,跳到如下:调用 handle() 方法,进行反射调用目标 Handler。
(7)点击 step into,进入到 handle 方法中调用的 handleInternal() 方法,handleInternal() 方法中反射调用了目标 Handler的方法,然后返回视图对象。
(8)在目标方法中打上断点,点击 resume 进入目标方法
(9)点击 step over,ModelAndView 对象返回给适配器。
(10)然后返回到第7步的方法中,因此第7步中返回的视图就是目标方法操作后返回的视图对象
(11)继续一直点击 step over,方法 return 返回到第6步,将获取的视图对象返回给前端控制器。
(12)点击 step over,在前端控制器的 doService 方法中执行如下语句,processDispatchResult() 方法对前面返回的视图进行解析。
(13)step into 进入processDispatchResult 方法,该方法调用 render() 进行渲染。
(14)render() 方法从 ModelAndView 对象中得到视图名称 viewName,如果 viewName 不为空,就进行视图解析。
resolveViewName() 方法进行视图解析,然后返回 view 给前端控制器。 @Nullableprotected View resolveViewName(String viewName, @Nullable Map model, Locale locale, HttpServletRequest request) throws Exception { if (this.viewResolvers != null) { for (ViewResolver viewResolver : this.viewResolvers) { View view = viewResolver.resolveViewName(viewName, locale); if (view != null) { return view; } } } return null;}
(15)返回前端控制器之后,又调用 View的 render() 方法进行视图的渲染。
注意和前端控制器的 render 方法区分
View 的 render() 方法: @Overridepublic void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { if (logger.isDebugEnabled()) { logger.debug("View " + formatViewName() + ", model " + (model != null ? model : Collections.emptyMap()) + (this.staticAttributes.isEmpty() ? "" : ", static attributes " + this.staticAttributes)); } Map mergedModel = createMergedOutputModel(model, request, response); prepareResponse(request, response); //渲染合并输出模型 renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);}
renderMergedOutputModel() 方法通过请求转发跳转到相应页面:
(16)最后 tomcat 返回 http响应,浏览器显示页面
3.练习将之前的 SpringMVC 异常处理相关代码和案例写一遍 简述原生的 SpringMVC 执行流程,并画出示意图 debug SpringMVC 的执行流程源码,加深理解
年入22亿!70后白手起家,河南人吃出一个挂面第二股?新消费的热度熄了火,传统消费的IPO依旧停不下来。公开信息显示,想念食品股份有限公司(以下简称想念食品)拟沪市主板IPO,保荐人为国金证券。想念食品成立于2008年,聚焦挂面和面粉
重点2022中国县域投资竞争力百强研究报告重点内容一览作者县域经济研究中心投资作为稳增长调结构的先导指标,对供给结构起着决定性的作用,是补短板的内在要求,是促进供给产品新陈代谢的加速器,是促进区域协同发展的必然选择,是推动乡村振兴的重
上车的最佳时机来了!刚需人群一定要看完11月11日,据媒体报道,央行银保监共同发布关于做好当前金融支持房地产市场平稳健康发展工作的通知,内容涉及保持房地产融资平稳有序积极做好保交楼金融服务积极配合做好受困房地产企业风险
金融数字化调查银行手机银行打好月活攻坚战编者按年初,央行印发金融科技发展规划(20222025年),要求高质量推进金融数字化转型。对金融业而言,构建以数据为中心的现代金融服务体系,是数字经济的时代要求,从这个意义上,金融
45年后的今天,旅行者探测器仍在飞行,7万年后到达比邻星如果有一天人类消失了,地球在灾难中变得千疮百孔,高楼大厦被自然逐渐磨成碎石,宇宙中是否有什么东西能证明辉煌的人类文明曾经存在过?答案是有的,只不过它并不在地球上,而是在距离人类几百
千眼天珠,观天逐日在稻城作者吴季阎敬业(均系中国科学院国家空间科学中心研究员)在四川省稻城县金珠镇的花海间,藏着一个由数百面白色反射面天线组成的巨大的圆环形望远镜阵列,圆环的正中心有一个约百米高的铁塔。这
传奇家族宿命之战!狼族再遇布拉格,短短两小时双方狂砍上万击杀相信不少传奇玩家都还记得当年狼族和布拉格的世纪之战,结果没想到,昨天开打的996传奇争霸赛海选赛中,成功复刻了当年的战役,布拉格二战区对决狼族总部,双方指挥全程激情嘶吼,比分焦灼,
没有什么阳关道是过不去的11月24日,感恩节。上完网课以后,突然活蹦乱跳的我感觉鼻塞和头疼。哦,我是一个孕晚期的孕妇,这一天的胎动异常频繁。估计胎宝宝都感觉到了不舒服。当天没有食欲,吃不下饭,晚上才后知后
有湿疹或红屁股的宝宝该怎么洗澡呢?西安燕子月嫂育婴师分享1有湿疹的宝宝主要是原因是皮肤太干燥,因此要做好保湿。要是宝宝身上的湿疹大多为干燥的红斑,并没有流水结痂,那么没必要给宝宝洗得太过频繁,一周2次左右最好。主要是要做好皮肤保湿,观察
写给我最亲爱的(一)孩子你好!衷心地希望你一切都好。因为我的世界有了一个你,最近我变得很焦虑!2022年8月21日,在外出差期间得知你可能要来到我们的世界后,我第一时间赶回家,在确认过后,忐忑和不安是
如何点燃孩子生命的发动机?经常听到不少家长的抱怨,教育孩子累啊,孩子像石磨,推一步走一步,不推就不走。不光我们累,孩子也累。为什么这么累呢?究其原因,我认为就是因为孩子自身的发动机没有被点燃。就像汽车一样,