创意电子

标题: 万字长文,深度解析SpringMVC 源码,让你醍醐灌顶 [打印本页]

作者: 程序猿阿嘴    时间: 2021-9-14 13:53
标题: 万字长文,深度解析SpringMVC 源码,让你醍醐灌顶
原文链接:https://mp.weixin.qq.com/s/KX3-CJxhTqmjZYQ8Ei6lUQ
本文将通过阅读源码的方式带大家相识 springmvc 处置惩罚请求的完备流程,干货满满。

目录



1、先相识下 SpringMVC 常用的 10 组件

1.1、DispatcherServlet:前端控制器

这个大家是最熟悉的,是一个 servlet,是 springmvc 处置惩罚请求的入口,不需要咱们开发,由框架提供。

作用:统一处置惩罚请求和相应,整个流程控制的中央,由它来调用其他组件处置惩罚用户的请求。

1.2、HandlerMapping:处置惩罚器映射器

作用:根据请求的信息(如 url、method、header 等)查找请求处置惩罚器,即找到自定义的 controller 中处置惩罚请求的方法。

HandlerMapping 接口源码如下,getHandler:根据请求查找请求处置惩罚器,会返回一个 HandlerExecutionChain 对象。

public interface HandlerMapping { HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;}
常见的实现类:

1.3、HandlerExecutionChain:处置惩罚器执行链

HandlerMapping#getHandler 方法会根据请求得到一个 HandlerExecutionChain 对象。

HandlerExecutionChain 源码如下,主要包罗了 3 个信息

public class HandlerExecutionChain { private final Object handler; private final List interceptorList = new ArrayList(); private int interceptorIndex = -1;}1.4、handler:处置惩罚器

通常需要我们自己开发,一般指我们自定义的 controller,在 DispatcherServlet 的控制下 handler 对具体的请求举行处置惩罚。

1.5、HandlerAdapter:处置惩罚器适配器

他负责对 handler 的方法举行调用,由于 handler 的类型大概有很多种,每种 handler 的调用过程大概不一样,此时就需要用到适配器 HandlerAdapte,适配器对外暴露了统一的调用方式(见其 handle 方法),内部将 handler 的调用过程屏蔽了,HandlerAdapter 接口源码如下,主要有 2 个方法需要留意:

public interface HandlerAdapter { boolean supports(Object handler); @Nullable ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;}
常见的实现类:

1.6、ModelAndView:模型和视图

这个对象中主要用来存放视图的名称和共享给客户端的数据。

public class ModelAndView { /*视图*/ @Nullable private Object view; /*模型,用来存放共享给客户端的数据*/ @Nullable private ModelMap model;}1.7、ViewResolver:视图解析器

这个是框架提供的,不需要咱们自己开发,它负责视图解析,根据视图的名称得到对应的视图对象(View)。

ViewResolver 接口源码

public interface ViewResolver { @Nullable View resolveViewName(String viewName, Locale locale) throws Exception;}
这个接口有很多实现类,比如 jsp 的、freemarker、thymeleaf 的等,他们都有各自对应的 ViewResolver。

而比较常的实现类是InternalResourceViewResolver,这个大家应该比较熟悉吧,目前为止我们前面的文章用到的都是这个视图解析器,用来处置惩罚 jsp 格式的视图页面,带大家再回顾一下这个类的配置,如下

        
InternalResourceViewResolver 比较重要,这里说下这个类的 resolveViewName 方法获取视图的过程,大家也可以去阅读InternalResourceViewResolver#resolveViewName方法得到,大致的过程如下:

step1:判断视图 viewName 是否以redirect:开头,假如是,则返回RedirectView类型的视图对象,RedirectView 是用来重定向的,RedirectView 内部用到的是response.sendRedirect(url)举行页面重定向;否则继续向下 step2

step2:判断 viewName 是否以forward:开头,假如是,则返回InternalResourceView类型的视图对象,InternalResourceView 是用来做跳转的,InternalResourceView 内部用到的是request.getRequestDispatcher(path).forward(request, response)举行页面跳转;否则继续向下 step3

step3:判断当前项目是否存在 jstl 所需的类,假如是,则返回 JstlView 类型的视图,否则返回 InternalResourceView 类型的视图,这两个视图的 render 方法终极会通过request.getRequestDispatcher(path).forward(request, response)举行页面的跳转,跳转的路径是:InternalResourceViewResolver 的前缀 prefix + viewName+InternalResourceViewResolver 的后缀 prefix

1.8、View:视图

负责将结果展示给用户,View 接口源码如下,render 方法根据指定的模型数据(model)渲染视图,即 render 方法负责将结果输出给客户端。

public interface View { void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response)   throws Exception;}
View 接口常见的 2 个实现类

1.9、HandlerExceptionResolver:处置惩罚器异常解析器

负责处置惩罚异常的,HandlerExceptionResolver 接口有个resolveException方法,用来解析异常,返回异常环境下对应的 ModelAndView 对象

public interface HandlerExceptionResolver { @Nullable ModelAndView resolveException(   HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);}1.10、HttpMessageConverter:http 报文转换器

将请求报文转换为 Java 对象,或将 Java 对象转换为相应报文,在处置惩罚@RequestBody、RequestEntity、@ResponseBody、ResponseEntity 的时候会用到

public interface HttpMessageConverter { /**  * 是否可以将请求保温读取给方法参数指定的类型  */ boolean canRead(Class clazz, @Nullable MediaType mediaType); /**  * 是否可以将相应的保温转换为方法参数指定的类型输出  */ boolean canWrite(Class clazz, @Nullable MediaType mediaType); /**  * 当前转换器支持的类型  */ List getSupportedMediaTypes(); /**  * 当前转换器支持的类型  */ default List getSupportedMediaTypes(Class clazz) {  return (canRead(clazz, null) || canWrite(clazz, null) ?    getSupportedMediaTypes() : Collections.emptyList()); } /**  * 将http保温转换为给定的类型,然后返回  */ T read(Class
作者: 牧涯475    时间: 2021-9-14 18:51
转发了




欢迎光临 创意电子 (https://wxcydz.cc/) Powered by Discuz! X3.4