精尽Spring MVC源码分析 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读
Spring 版本:5.1.14.RELEASE
该系列其他文档请查看:《精尽 Spring MVC 源码分析 - 文章导读》
HandlerMapping 组件
HandlerMapping 组件,请求的处理器匹配器,负责为请求找到合适的 HandlerExecutionChain
处理器执行链,包含处理器(handler
)和拦截器们(interceptors
)
handler
处理器是 Object 类型,可以将其理解成 HandlerMethod 对象(例如我们使用最多的@RequestMapping
注解所标注的方法会解析成该对象),包含了方法的所有信息,通过该对象能够执行该方法HandlerInterceptor
拦截器对处理请求进行增强处理,可用于在执行方法前、成功执行方法后、处理完成后进行一些逻辑处理
由于 HandlerMapping 组件涉及到的内容比较多,考虑到内容的排版,所以将这部分内容拆分成了四个模块,依次进行分析:
HandlerMapping 组件(二)之 HandlerInterceptor 拦截器
在上一篇《HandlerMapping 组件(一)之 AbstractHandlerMapping》文档中分析了 HandlerMapping 组件的 AbstractHandlerMapping 抽象类,在获取HandlerExecutionChain
处理器执行链时,会去寻找匹配的 HandlerInterceptor 拦截器们,并添加到其中。那么本文将分享 Spring MVC 的拦截器相关内容
HandlerInterceptor
org.springframework.web.servlet.HandlerInterceptor
,处理器拦截器接口,代码如下:
public interface HandlerInterceptor {/** * 前置处理,在 {@link HandlerAdapter#handle(HttpServletRequest, HttpServletResponse, Object)} 执行之前 */default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}/** * 后置处理,在 {@link HandlerAdapter#handle(HttpServletRequest, HttpServletResponse, Object)} 执行成功之后 */default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {}/** * 完成处理,在 {@link HandlerAdapter#handle(HttpServletRequest, HttpServletResponse, Object)} 执行之后(无论成功还是失败) * 条件:执行 {@link #preHandle(HttpServletRequest, HttpServletResponse, Object)} 成功的拦截器才会执行该方法 */default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable Exception ex) throws Exception {}}
HandlerExecutionChain
org.springframework.web.servlet.HandlerExecutionChain
,处理器执行链,也就是通过 HandlerMapping 组件为请求找到的处理对象,包含处理器(handler
)和拦截器们(interceptors
)
构造方法
public class HandlerExecutionChain {/** * 处理器 */private final Object handler;/** * 拦截器数组 */@Nullableprivate HandlerInterceptor[] interceptors;/** * 拦截器数组。 * * 在实际使用时,会调用 {@link #getInterceptors()} 方法,初始化到 {@link #interceptors} 中 */@Nullableprivate List<HandlerInterceptor> interceptorList;/** * 已成功执行 {@link HandlerInterceptor#preHandle(HttpServletRequest, HttpServletResponse, Object)} 的位置 * * 在 {@link #applyPostHandle} 和 {@link #triggerAfterCompletion} 方法中需要用到,用于倒序执行拦截器的方法 */private int interceptorIndex = -1;public HandlerExecutionChain(Object handler) {this(handler, (HandlerInterceptor[]) null);}public HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... interceptors) {if (handler instanceof HandlerExecutionChain) {HandlerExecutionChain originalChain = (HandlerExecutionChain) handler;this.handler = originalChain.getHandler();this.interceptorList = new ArrayList<>();// 将原始的 HandlerExecutionChain 的 interceptors 复制到 this.interceptorList 中CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);// 将入参的 interceptors 合并到 this.interceptorList 中CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);} else {this.handler = handler;this.interceptors = interceptors;}}}
handler
:请求对应的处理器对象,可以先理解为HandlerMethod
对象(例如我们常用的@RequestMapping
注解对应的方法会解析成该对象),也就是我们的某个 Method 的所有信息,可以被执行interceptors
:请求匹配的拦截器数组interceptorList
:请求匹配的拦截器集合,至于为什么要该属性,我还没看明白