首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Spring MVC 攔截器 preHandle 中 handler 類型判斷的深層含義

     編輯:程式設計疑難解答

代碼片段


public boolean preHandle(HttpServletRequest request,
                         HttpServletResponse response,
                         Object handler) throws Exception {
    if (!(handler instanceof HandlerMethod)) {
        return true; // 直接放行
    }
    // 後續處理:權限校驗、日誌、參數解析等
    ...
}

核心問題:為什麼要判斷 `handler instanceof HandlerMethod`?

Handler 可能的類型

Spring MVC 的 `HandlerMapping` 返回的 `handler` 不僅僅是控制器方法,還包括:

  • HandlerMethod:`@RequestMapping` 映射的控制器方法(最常見)。
  • HttpRequestHandler:實現 `HttpRequestHandler` 接口的 Bean。
  • WebRequestHandler:實現 `WebRequestHandler` 接口的 Bean。
  • ResourceHttpRequestHandler:靜態資源處理器(CSS/JS/圖片)。
  • ServletForwardingController:轉發到 Servlet/JSP。

判斷邏輯解讀


if (!(handler instanceof HandlerMethod)) {
    return true; // 非控制器方法請求(靜態資源、Servlet 轉發等)直接放行,不攔截
}
// 只有 HandlerMethod 才執行後續業務攔截邏輯(權限、日誌、參數綁定等)

設計意圖

  1. 性能優化:避免對靜態資源、內部轉發等非業務請求執行重攔截邏輯。
  2. 職責分離:攔截器專注於「控制器方法級」的橫切關注點(Auth、Log、Transaction),不干擾框架基礎設施請求。
  3. 類型安全:後續代碼常需強轉 `(HandlerMethod) handler` 獲取方法註解、參數信息,前置判斷避免 `ClassCastException`。

實戰最佳實踐


@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    // 1. 非 HandlerMethod 直接放行
    if (!(handler instanceof HandlerMethod)) return true;

    HandlerMethod hm = (HandlerMethod) handler;

    // 2. 方法級註解跳過攔截(如 @NoAuth、@NoLog)
    if (hm.hasMethodAnnotation(NoAuth.class)) return true;

    // 3. 類級註解跳過
    if (hm.getBeanType().isAnnotationPresent(NoAuth.class)) return true;

    // 4. 核心業務邏輯:Token 校驗、簽名驗證、限流等
    return checkPermission(request, hm);
}

總結

handler instanceof HandlerMethod 是 Spring MVC 攔截器的**標準守衛條款**,精準劃定攔截邊界:只攔截「帶有業務語義的控制器方法請求」,放行框架內部與靜態資源請求,兼顧性能與架構純淨度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved