- 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屬性中獲取。