赞
踩
Spring MVC中各组件初始化过程已在上篇分享
:初始化过程
DispatcherServlet:前端控制器
,统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求
HandlerMapping:处理器映射器
,根据请求的url、method等信息查找Handler,即控制器方法
Handler:处理器
,在DispatcherServlet的控制下Handler对具体的用户请求进行处理
HandlerAdapter:处理器适配器
,通过HandlerAdapter对处理器(控制器方法)进行执行
ViewResolver:视图解析器
,不需要工程师开发,由框架提供,进行视图解析
View:视图
将模型数据通过页面展示给用户
IDEA中快捷键Ctrl+Shift+Alt+U
可查看继承图
从上图中可以看到DispatcherServlet的顶层接口是
Servlet
虽然我们看的是不同类中的调用过程 , 如果通过继承或者实现放到同一个类中 \color{#F00}{虽然我们看的是不同类中的调用过程,如果通过继承或者实现放到同一个类中} 虽然我们看的是不同类中的调用过程,如果通过继承或者实现放到同一个类中
其实我们就是在同一个类中来查看方法的调用。 \color{#F00}{其实我们就是在同一个类中来查看方法的调用。} 其实我们就是在同一个类中来查看方法的调用。
从Servlet接口开始步步分析,在Servlet接口中存在下图中的5种抽象方法。
快捷键: Alt+7
用户每次发送请求时,Servlet容器都会调用
service()
方法对请求进行处理
public interface Servlet {
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
}
public abstract class GenericServlet implements Servlet, ServletConfig,
java.io.Serializable {
//可以看到并没有对Servlet中的service()方法进行实现
@Override
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
}
GenericServlet没有对Servlet中的service()方法进行实现,那么根据继承结构继续向下梳理
可以看到又调用了
service(request, response)
方法,如下图
请求方式有以下几种
根据
req.getMethod()
获取请求方式调用对应的doGet,doPut等等
方法,继续向下看
可以发现HttpServletBean没有重写
service()
方法,用的是父类HttpServle中的方法
FrameworkServlet中重写了
doGet
等方法,则使用本类中重写后的方法
可以看到无论service中的那个逻辑,都执行
processRequest(request, response)
方法,所以我们只需查看该方法即可
为什么说doDispatcher()是整个流程控制的中心,由它调用其它组件处理用户的请求? 那么看下文流程即可明白
用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获。
执行流程图
大家可以对照图来看接下来的流程
2,3
步处理器映射器
就是这一步返回处理器执行链包含拦截器
当前类重写了父类中的
doservice
()方法,又发现该方法的核心是doDispatcher
方法,重点来了
我们来看该方法实现
4,5,6,7
步处理器适配器
接下来就到拦截器的前置方法,首先看下拦截器的执行顺序,方便理解接下来的代码流程
请欣赏源码流程:
紧接上图中的适配器方法
拦截器的前置方法
对应上图的逻辑处理(对上图详解)
正序
下来是实际调用处理程序方法 返回ModelAndView对象
拦截器的后置方法
8,9,10
步>进入该方法查看
看拦截器的最后执行方法
返回用户
1
. Spring MVC所有的请求都经过DispatcherServlet来统一分发。DispatcherServlet将请求分发给Controller之前,需要借助于Spring MVC提供的HandlerMapping定位到具体的Controller。
2
. HandlerMapping接口负责完成客户请求到Controller映射。
3
. Controller接口将处理用户请求,这和Java Servlet扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView(数据和视图)对象给DispatcherServlet前端控制器。从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观考虑,Controller是单个Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。
4
.返回的视图需要通过ViewResolver接口(视图解析器)在Web应用中负责查找View对象,从从而将相应结果渲染给客户。
1
. 用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获
2
. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),判断请求URI对应的映射
3
. 根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain执行链对象的形式返回。
4
. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。
5
. 如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler(…)方法【正向】
6
. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
6.1
. HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
6.2
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
6.3
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
6.4
数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
6.5
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
7
. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象。
8
. 此时将开始执行拦截器的postHandle(…)方法【逆向】。
9
. 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver进行视图解析,根据Model和View,来渲染视图。
10
. 渲染视图完毕执行拦截器的afterCompletion(…)方法【逆向】。
11
. 将渲染结果返回给客户端。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。