简述springmvc执行流程(day15-SpringMVC执行流程)
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.练习
将之前的 SpringMVC 异常处理相关代码和案例写一遍 简述原生的 SpringMVC 执行流程 ,并画出示意图 debug SpringMVC 的执行流程源码 ,加深理解创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!