分享

精尽Spring MVC源码分析 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器

 行者花雕 2021-06-15

该系列文档是本人在学习 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;

/**
 * 拦截器数组
 */
@Nullable
private HandlerInterceptor[] interceptors;

/**
 * 拦截器数组。
 *
 * 在实际使用时,会调用 {@link #getInterceptors()} 方法,初始化到 {@link #interceptors} 中
 */
@Nullable
private 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:请求匹配的拦截器集合,至于为什么要该属性,我还没看明白 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多