springMvc源码解读--AbstractUrlHandlerMapping

  • 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属性中获取。

相关推荐