目录
写文章不易,转载请标明出处。
同时,如果你喜欢我的文章,请关注我,让我们一起进步。
一、概述
通过上一篇博文中对 SpringMVC 处理请求流程的源码分析,已经对 SpringMVC 中的部分核心类有了一个大概的印象,但是因为没有分析过每部分组件的具体作用,因此还是一种比较模糊的状态。所以在这篇博文中先对 SpringMVC 中三个比较核心的基础接口和类(HandlerMapping、HandlerAdapter 以及 HandlerExecutionChain)进行第一次简要的分析,主要是通过接口和类源码以及官方文档的阅读来了解这三个核心基础接口和类的作用以及其涉及的部分技术。
二、功能介绍和部分源码解析
2.1 HandlerMapping
public interface HandlerMapping {
String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";
String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
@Nullable
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
首先,明确一下 HandlerMapping 是一个顶层接口(其只提供了一个方法 getHandler),用于定义请求和处理器之间的映射关系,通俗来将就是通过什么样的方式将一个请求映射到它对应的处理器上。其次, HandlerMapping 也支持对于 HandlerInterceptor 拦截器的映射,但一般来说会将处理器 Handler 包装在 HandlerExecutionChain 实例中,并在 HandlerExecutionChain 中可选地伴随一些 HandlerInterceptor 实例(最终外部通过 getHandler 方法获取到的 Handler 其实也是 HandlerExecutionChain 实例),在 DispatcherServlet 中(doDispatch 方法)会按照我们给定的顺序执行所有的 HandlerInterceptor 拦截器的 preHandle 方法,并且只有当所有的 preHandle 方法都返回 true 时才会调用 HandlerAdapter 的 handle 的方法来处理请求。
对于 HandlerMapping 的实现也可以通过实现 Order 接口来支持排序,此时没有实现 Order 接口的类实例会处于最低优先级。然后,我们来谈一下 HandlerMapping 这种实现方式的优点,参数化映射的功能使 SpringMVC 具备强大而独特的功能,例如我们可以根据会话状态(session state),cookie 状态(cookie state)或许多其他变量来编写自定义的映射,这让 SpringMVC 相比于其他 MVC 框架具备更高的灵活性 。
需要注意的是这里的 HandlerMapping 也是通过 Java 的 SPI