springMvc原始碼解讀–AbstractUrlHandlerMapping

雨露發表於2019-01-19
  • AbstractUrlHandlerMapping系列都是繼承於AbstractUrlHandlerMapping,它是通過URL來進行匹配的,是將URL與對應的handler儲存在一個map中,在getHandlerInternal方法中使用URL從map中獲取handler,AbstractUrlHandlerMapping中實現了具體用URL從map中獲取handler的過程,而將map的初始化則交給了具體的子類去完成。這裡的map就是定義在AbstractUrlHandlerMapping中的handlerMap,另外還單獨定義了處理“/”請求的處理器rootHandler。

handler的入口是getHandlerInternal,具體實現如下:
/* Java

@Override
@Nullable
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
    String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
    Object handler = lookupHandler(lookupPath, request);
    if (handler == null) {
        // We need to care for the default handler directly, since we need to
        // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
        Object rawHandler = null;
        if ("/".equals(lookupPath)) {
            rawHandler = getRootHandler();
        }
        if (rawHandler == null) {
            rawHandler = getDefaultHandler();
        }
        if (rawHandler != null) {
            // Bean name or resolved handler?
            if (rawHandler instanceof String) {
                String handlerName = (String) rawHandler;
                rawHandler = obtainApplicationContext().getBean(handlerName);
            }
            validateHandler(rawHandler, request);
            handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
        }
    }
    if (handler != null && logger.isDebugEnabled()) {
        logger.debug("Mapping [" + lookupPath + "] to " + handler);
    }
    else if (handler == null && logger.isTraceEnabled()) {
        logger.trace("No handler mapping found for [" + lookupPath + "]");
    }
    return handler;
}

*/
這裡lookupHandler方法用於使用lookupPath從map中查詢handler,不過很多時候不能從map中直接get到結果,因為很多handler都是用了pattern的匹配模式,如“/getData/*”,這裡的星號可以代表任意內容而不是真正的匹配URL中的星號,buildPathExposingHandler方法的作用是用於查詢到的handler註冊兩個攔截器PathExposingHandlerInterceptor和UriTemplateVariablesHandlerInterceptor,這是兩個內部攔截器,主要作用是將與當前URL實際匹配的pattern、匹配條件,和URL模版引數等設定到request的屬性裡,這樣在後面的處理過程中可以直接從request屬性中獲取。

相關文章