Spring入门进阶之DispatcherServlet源码分析(5)

// There might be multiple 'best patterns', let's make sure we have the correct URI template variables
        // for all of them
        Map<String, String> uriTemplateVariables = new LinkedHashMap<String, String>();
        for (String matchingPattern : matchingPatterns) {
            if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {
                Map<String, String> vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
                Map<String, String> decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
                uriTemplateVariables.putAll(decodedVars);
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
        }
        return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
    }
    // No handler found...
    return null;
}

这里考虑了直接匹配和通配符两种情况,其中在buildPathExposingHandler方法里将Handler封装成了HandlerExecutionChain类型。看buildPathExposingHandler方法源码:

protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern,
        String pathWithinMapping, Map<String, String> uriTemplateVariables) {

HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
    chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
    if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
        chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
    }
    return chain;
}

在该方法中可以看到通过将Handler以参数形式传入,再构建HandlerExecutionChain类型实例,加入了两个拦截器,这里也是链式处理方式。

根据当前Handler寻找对应的HandlerAdapter

在默认情况下普通web请求会由SimpleControllerHandlerAdapter处理,下面分析获取适配器的逻辑:

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    for (HandlerAdapter ha : this.handlerAdapters) {
        if (Logger.isTraceEnabled) {
            Logger.trace("Testing handler adapter ["+ha+"]");
        }
        if (ha.supports(handler)) {
            return ha;
        }
    }
}

通过该方法可以看出对于获取适配器的逻辑就是遍历所有适配器来选择合适的并返回它,而某个适配器是否适用于当前的Handler逻辑被封装在具体的适配器中,看SimpleControllerHandlerAdapter中的supports方法,

public boolean supports(Object handler) { return (handler instanceof Controller); }

SimpleControllerHandlerAdapter就是用于处理普通web请求的,对于SpringMVC来说,一般是把逻辑封装到Controller的子类中。

继续返回到doDispatcher方法中的激活handler并返回视图的代码,

// 激活handler并返回视图 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

对于普通的Web请求,Spring默认是使用SimpleControllerHandlerAdapter类进行处理的, 进入SimpleControllerHandlerAdapter类的handle方法如下:

public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); }

之前举例的controller的逻辑是写在handleRequestInternal方法中而不是handleRequest方法中的,看看该方法中的处理逻辑:

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws Exception {

// Delegate to WebContentGenerator for checking and preparing.
    checkAndPrepare(request, response, this instanceof LastModified);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/336c8119869d60547179f91a2051b66d.html