SpringMVC 攔截器原理


前言

SpringMVC 攔截器也是Aop(面向切面)思想構建,但不是 Spring Aop 動態代理實現的,
主要采用責任鏈和適配器的設計模式來實現,直接嵌入到 SpringMVC 入口代碼里面。

流程分析

瀏覽器請求

DispatcherServlet 執行調用 doService(request, response) 作為 Servlet 主要執行者,
doService(request, response) 通過調用 doDispatch(request, response) 來真正執行請求處理

doDispatch(request, response) 中完成攔截器的添加和攔截器攔截處理
    通過 getHandler(HttpServletRequest request) 獲取到 HandlerExecutionChain 處理器執行鏈,
    將攔截器注入到 HandlerExecutionChain 的屬性中。
    分別調用 HandlerExecutionChain 的三個方法,applyPreHandle、applyPostHandle、triggerAfterCompletion,
    實現前置攔截/請求提交攔截和請求完成后攔截。
    使用責任鏈的設計模式,實際調用的是HandleInterceptor的三個接口,分別對應preHandle、postHandle、afterCompletion

HandlerExecutionChain 源碼分析

public class HandlerExecutionChain {

    private final Object handler;
    @Nullable
    private HandlerInterceptor[] interceptors;
    @Nullable
    private List<HandlerInterceptor> interceptorList;
    private int interceptorIndex;

    /**
      按照列表中interceptor的順序來執行它們的preHandle方法,直到有一個返回false。
      true:表示繼續流程(如調用下一個攔截器或處理器)
      返回false后:表示流程中斷(如登錄檢查失敗),不會繼續調用其他的攔截器或處理器,
      調用triggerAfterCompletion方法,此時this.interceptorIndex指向上一個返回true的interceptor的位置,
      所以它會按逆序執行所有返回true的interceptor的afterCompletion方法。
    */
    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    this.triggerAfterCompletion(request, response, (Exception)null);
                    return false;
                }
            }
        }

        return true;
    }

    /**
      按照逆序執行所有interceptor的postHandle方法
    */
    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = interceptors.length - 1; i >= 0; --i) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }

    }

    /**
      從最后一次preHandle成功的interceptor處逆序執行afterCompletion方法。
    */
    void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = this.interceptorIndex; i >= 0; --i) {
                HandlerInterceptor interceptor = interceptors[i];

                try {
                    interceptor.afterCompletion(request, response, this.handler, ex);
                } catch (Throwable var8) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
                }
            }
        }

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM