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
*/
@Controller
public 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" %>
<html>
<head>
<title>ok</title>
</head>
<body>
<h1>进入到ok页面</h1>
<h2>name-${requestScope.name}</h2>
</body>
</html>

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 给前端控制器。

@Nullable
protected View resolveViewName(String viewName, @Nullable Map<String, Object> 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() 方法:

@Override
public void render(@Nullable Map<String, ?> 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<String, Object> mergedModel = createMergedOutputModel(model, request, response);
prepareResponse(request, response);
//渲染合并输出模型
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}

renderMergedOutputModel() 方法通过请求转发跳转到相应页面:


(16)最后 tomcat 返回 http响应,浏览器显示页面

3.练习

  1. 将之前的 SpringMVC 异常处理相关代码和案例写一遍
  2. 简述原生的 SpringMVC 执行流程,并画出示意图
  3. debug SpringMVC 的执行流程源码,加深理解

day15-SpringMVC执行流程的更多相关文章

  1. springmvc执行流程详细介绍

    1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...

  2. springMVC执行流程及原理

    spring的MVC执行原理 1.spring mvc将所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求 进行真正的处理工作. 2.DispatcherSer ...

  3. 2.SpringMVC执行流程

    SpringMVC 执行流程: 执行流程简单分析: 1.浏览器提交请求到中央调度器 2.中央调度器直接将请求转给处理器映射器 3.处理器映射器会根据请求,找到处理该请求的处理器,并将其封装为处理器执行 ...

  4. SpringMvc执行流程及底层代码流程

    SpringMVC执行流程   01.客户端发送请求被我们在web.xml中配置DispatcherServlet(核心控制器)拦截: 默认执行DispatcherServlet中的 protecte ...

  5. 面试高频SpringMVC执行流程最优解(源码分析)

    文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各种学习资料! SpringMVC执行流程 SpringMVC概述 Spri ...

  6. SpringMVC执行流程总结

    SpringMVC 执行流程: 用户发送请求至前端控制器 DispatcherServlet DispatcherServlet 收到请求调用处理映射器 HandlerMapping 处理映射器根据请 ...

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

    ✿ 阅读源码思路: 先跳过非重点,深入每个方法,进入的时候可以把整个可以理一下方法的执行步骤理一下,也可以,理到某一步,继续深入,回来后,接着理清除下面的步骤. ✿ 阅读本文的准备工作,预习一下Spr ...

  8. Servlet、Struts2、SpringMVC执行流程

    Servlet 有以下四个阶段: 1.加载和实例化 Servlet容器负责加载和实例化Servlet. 当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Ser ...

  9. SSM-SpringMVC-01:SpringMVC是什么?SpringMVC执行流程

     ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- SpringMVC简介: SpringMVC也叫Spring Web  mvc,属于表现层的框架.Sprin ...

  10. springMVC执行流程及架构

    目录 springMVC简单执行流程 springMVC框架 注解实现 springMVC简单执行流程 springMVC框架 执行流程: 1.用户发送请求至前端控制器DispatcherServle ...

随机推荐

  1. C++初阶(list容器+模拟实现)

    list介绍 list的本质是一个带头的双向循环链表. 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点 ...

  2. .NET性能优化-使用内存+磁盘混合缓存

    我们回顾一下上一篇文章中的内容,有一个朋友问我这样一个问题: 我的业务依赖一些数据,因为数据库访问慢,我把它放在Redis里面,不过还是太慢了,有什么其它的方案吗? 其实这个问题比较简单的是吧?Red ...

  3. 原来 GitHub 不仅能学代码,还有这些东西

    我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 大家好,我是风筝. 今天介绍几 ...

  4. Springcoud-netflix 笔记

    SpringCloud_Netflix 微服务一代(Netflix)学习前提: JAVASE. 数据库(MySQL). 前端(HTML+CSS+JavaScript||JQuery.Bootstrap ...

  5. 【每日一题】【哈希表,返回结果的下标】2022年1月18日-NC61 两数之和

    描述给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列.(注:返回的数组下标从1开始算起) 算法: import java ...

  6. VMware虚拟机开机黑屏解决方法

    挂起时可以看到显示,但是开机就黑屏 解决方法: 命令提示符,鼠标右键点击"命令提示符",弹出菜单之后选择"以管理员身份运行" 在命令提示符窗口中输入" ...

  7. CMS可视化---ECharts图表

    一.ECharts介绍 ECharts,全称Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,能够流畅的运行在PC以及移动设备上,兼容当前绝大部分浏览器.为我们许 ...

  8. 侦察工具——Httrack

    前言 web渗透学习笔记,实验环境为Metasploitable靶机上的DVWA.此随笔介绍Web渗透侦察工具Httrack Httrack 简介 Httrack能够克隆拷贝目标网站上的所有可访问.可 ...

  9. [cocos2d-x]关于动画

    声明一下:看见这篇文章总结的已经非常好了,没必要再去自己到处东翻西找了,链接:http://shahdza.blog.51cto.com/2410787/1546998 [唠叨] 基本动画制作需要用到 ...

  10. 解决angular11+zorro使用table组件排序失效以及分页组件失效问题,附完整DEMO代码

    关于这个排序失效问题的核心点,跟这个有关系:[nzFrontPagination]="false" 关于分页组件失效的问题,是你获取数据以后,需要给页码,页数,总条数都要重新赋值, ...