SpringMVC-DispatcherServlet 源码分析
SpringMVC-DispatcherServlet 源码分析
SpringMVC 常用组件
-
DispatcherServlet:前端控制器,不需要开发者开发,由框架提供
作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求
-
HandlerMapping:处理器映射器,不需要开发者开发,由框架提供,
作用:根据请求的 url、method 等信息查找 Handler,即控制器方法
详见《SpringMVC 控制器方法(handler)的映射 - HandlerMapping》
-
Handler:处理器,需要开发者开发,一般为控制器方法,实际上有很多种其他的类型,比如
HttpRequestHandler
和Controller
接口的实现类作用:在 DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理
-
HandlerAdapter:处理器适配器,不需要开发者开发,由框架提供
作用:通过 HandlerAdapter 对处理器(控制器方法)进行执行
详见《SpringMVC 控制器方法(handler)适配器 - HandlerAdapter》
-
ViewResolver:视图解析器,不需要工程师开发,由框架提供
作用:进行视图解析,得到相应的视图,例如:ThymeleafView、InternalResourceView、RedirectView
-
View:视图,需要开发者自己编写。
作用:将模型数据通过页面展示给用户
经过 SpringMVC 的封装,只有控制器和视图需要开发者自己编写,大大减少了开发者的工作。
doDispatch 执行之前 - DispatcherServlet 初始化
具体详情,请看《从基于 Java 配置 Spring MVC 看 Spring MVC 加载过程中的容器初始化的相关源码解析》,将此文档转化为 markdown 文件之后,再引用过来
FrameworkServlet 创建 WebApplicationContext 后,刷新容器,调用 onRefresh(wac),此方法在 DispatcherServlet 中进行了重写,调用了 initStrategies(context) 方法,初始化策略,即初始化 DispatcherServlet 的各个组件。
initStrategies
protected void initStrategies(ApplicationContext context) {
// 文件上传解析器
initMultipartResolver(context);
// 本地信息解析器,用于国际化
initLocaleResolver(context);
initThemeResolver(context);
// 处理器映射
initHandlerMappings(context);
// 处理器适配
initHandlerAdapters(context);
// 处理器异常解析策略
initHandlerExceptionResolvers(context);
// 从请求中获取视图名的策略
initRequestToViewNameTranslator(context);
// 视图解析器解析策略
initViewResolvers(context);
initFlashMapManager(context);
}
各个初始化方法的内容跟其实大同小异,都是从 context 参数,也就是在注册到 IOC 中的所有组件中查找找到特定类型的组件,然后存放到 DispatcherServlet
的相应的字段里面。以备在后续进行请求处理时(调用 DispatcherServlet#doDispatch
时)使用。
doDispatch 之前的执行流程
FrameworkServlet 重写 HttpServlet 中的 service() 和 doXxx(),这些方法中调用了 processRequest(request, response),processRequest 调用 doService 方法,doService 由子类重写,即 DispatcherServlet 重写,DispatcherServlet 的 doService 方法调用 doDispatch
方法,终于来到我们熟悉的领域了。
doDispatch 执行流程
-
经过
HandlerMapping
进行处理器映射,获取 handler,实际上获取的是包含拦截器的处理器执行链HandlerExecutionChain
-
通过
HandlerExecutionChain
中最终的 handler,获取适配器HandlerAdapter
-
执行
HandlerAdapter#handle
方法执行处理器,获得ModelAndView
-
处理
ModelAndView
,如果有错误,就已经异常处理,渲染异常解析HandlerExceptionResolver
返回的ModelAndView
,如果没有错误,正常解析ModelAndView
详细版:
-
用户向服务器发送请求,请求被 SpringMVC 前端控制器 DispatcherServlet 捕获。
-
DispatcherServlet 对请求 URL 进行解析,得到请求资源标识符(URI),判断请求 URI 对应的映射,存在则执行下面的流程
-
根据该 URI,调用 HandlerMapping 获得该 Handler 配置的所有相关的对象(包括 Handler 对象以及 Handler 对象对应的拦截器),最后以 HandlerExecutionChain 执行链对象的形式返回。
-
DispatcherServlet 根据获得的 Handler,选择一个合适的 HandlerAdapter。
-
如果成功获得 HandlerAdapter,此时将开始执行拦截器的 preHandler(…) 方法【正向】
-
提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller) 方法,处理请求。在填充 Handler 的入参过程中,根据你的配置,Spring 将帮你做一些额外的工作:
a) HttpMessageConveter: 将请求消息(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息
b) 数据转换:对请求消息进行数据转换。如 String 转换成 Integer、Double 等
c) 数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
d) 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到 BindingResult 或 Error 中
-
Handler 执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象。
-
此时将开始执行拦截器的 postHandle(...) 方法【逆向】。
-
根据返回的 ModelAndView(此时会判断是否存在异常:如果存在异常,则执行 HandlerExceptionResolver 进行异常处理)选择一个适合的 ViewResolver 进行视图解析,根据 Model 和 View,来渲染视图。
-
渲染视图完毕执行拦截器的 afterCompletion(…) 方法【逆向】。
-
将渲染结果返回给客户端。