首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

SpringMVC 源碼解讀:HandlerMapping 之 AbstractUrlHandlerMapping 請求分發機制

     編輯:Java 相關知識

核心流程概覽

AbstractUrlHandlerMapping 是 SpringMVC 中基於 URL 映射的 HandlerMapping 基類,核心職責:根據請求路徑找到對應的 Handler,並封裝成 HandlerExecutionChain(包含攔截器鏈)。

關鍵方法解析

1. getHandlerInternal(HttpServletRequest request)

模板方法,子類實作具體查找邏輯(如 SimpleUrlHandlerMapping 從 Map 查找,RequestMappingHandlerMapping 掃描 @RequestMapping)。

2. getHandler(HttpServletRequest request)

入口方法,流程:

  1. 調用 getHandlerInternal 取得原始 Handler。
  2. 若為空,返回預設 Handler(若配置)。
  3. 驗證 Handler(validateHandler,預設空實現,子類可擴展)。
  4. 構建 HandlerExecutionChain:buildPathExposingHandler。

3. buildPathExposingHandler(...)

封裝 Handler 並添加兩個內建攔截器:

  • PathExposingHandlerInterceptor:暴露 bestMatchingPattern、pathWithinMapping 到請求屬性,供後續處理器使用。
  • UriTemplateVariablesHandlerInterceptor:暴露 URI 模板變數(如 /user/{id} 中的 id)。
protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,
        String pathWithinMapping, Map uriTemplateVariables) {
    HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
    chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
    if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
        chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
    }
    return chain;
}

繼承體系與擴展點

  • AbstractHandlerMapping:頂層抽象類,定義 getHandler 模板、攔截器管理、CORS 支援。
  • AbstractUrlHandlerMapping:引入 URL 路徑匹配邏輯(UrlPathHelper、PathMatcher)。
  • AbstractDetectingUrlHandlerMapping:自動偵測 Controller 中的 URL 映射(已過時)。
  • RequestMappingHandlerMapping:現代 SpringMVC 核心,掃描 @RequestMapping、@GetMapping 等註解。

原始碼片段(簡化)

public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
    // ...
    @Override
    protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        Object handler = lookupHandler(lookupPath, request);
        return handler;
    }

    protected abstract Object lookupHandler(String lookupPath, HttpServletRequest request);

    protected void validateHandler(Object handler, HttpServletRequest request) throws Exception { }
    // buildPathExposingHandler 見上文
}

實戰啟示

  • 自定義 HandlerMapping 只需繼承 AbstractUrlHandlerMapping 並實作 lookupHandler。
  • 攔截器鏈的構建集中在 buildPathExposingHandler,可覆寫調整暴露屬性邏輯。
  • 理解 bestMatchingPattern 與 pathWithinMapping 的區別,有助於編寫通用攔截器。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved