1. 程式人生 > 其它 >spring 攔截器流程 HandlerInterceptor AsyncHandlerInterceptor HandlerInterceptorAdapter

spring 攔截器流程 HandlerInterceptor AsyncHandlerInterceptor HandlerInterceptorAdapter

HandlerInterceptor原始碼

3種方法:

  1. preHandle:攔截於請求剛進入時,進行判斷,需要boolean返回值,如果返回true將繼續執行,如果返回false,將不進行執行。一般用於登入校驗。
  2. postHandle:攔截於方法成功返回後,檢視渲染前,可以對modelAndView進行操作。
  3. afterCompletion:攔截於方法成功返回後,檢視渲染前,可以進行成功返回的日誌記錄。
public interface HandlerInterceptor {
    default boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.Object handler) throws java.lang.Exception { /* compiled code */ }

    default void postHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.Object handler, @org.springframework.lang.Nullable org.springframework.web.servlet.ModelAndView modelAndView) throws java.lang.Exception { /* compiled code */ }

    default void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.Object handler, @org.springframework.lang.Nullable java.lang.Exception ex) throws java.lang.Exception { /* compiled code */ }
}

AsyncHandlerInterceptor原始碼

jdk 8 以後,介面可以有預設實現,所以,儘量使用 HandlerInterceptor, 介面卡模式已經不建議使用了。

public interface AsyncHandlerInterceptor extends org.springframework.web.servlet.HandlerInterceptor {
    default void afterConcurrentHandlingStarted(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.Object handler) throws java.lang.Exception { /* compiled code */ }
}
// AsyncHandlerInterceptor中的afterConcurrentHandlingStarted()方法, 會在Controller方法非同步執行時開始執行, 但是Interceptor的postHandle()方法則是需要等到Controller的非同步執行完之後才能執行

我們只需要繼承HandlerInterceptorAdapter,並重寫afterCompletion一個方法即可,因為preHandle預設是true

執行流程總結如下:

  1. 攔截器執行順序是按照Spring配置檔案中定義的順序而定的。

  2. 會先按照順序執行所有攔截器的preHandle方法,一直遇到return false為止,比如第二個preHandle方法是return false,則第三個以及以後所有攔截器都不會執行。若都是return true,則按順序載入完preHandle方法。

  3. 然後執行主方法(自己的controller介面),若中間丟擲異常,則跟return false效果一致,不會繼續執行postHandle,只會倒序執行afterCompletion方法。

  4. 在主方法執行完業務邏輯(頁面還未渲染資料)時,按倒序執行postHandle方法。若第三個攔截器的preHandle方法return false,則會執行第二個和第一個的postHandle方法和afterCompletion(postHandle都執行完才會執行這個,也就是頁面渲染完資料後,執行after進行清理工作)方法。(postHandle和afterCompletion都是倒序執行)

部分內容借鑑於此部落格(表示感謝):https://blog.csdn.net/vincent_duan/article/details/100880498