美文网首页
DispatchServlet源码分析

DispatchServlet源码分析

作者: 猴猴猪027 | 来源:发表于2017-03-10 16:00 被阅读0次

    DispatchServlet类是spring MVC中最重要的组建之一。下面通过debug对整个处理流程有个基本的了解。

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
            HttpServletRequest processedRequest = request;
            HandlerExecutionChain mappedHandler = null;
            boolean multipartRequestParsed = false;
    
            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    
            try {
                ModelAndView mv = null;
                Exception dispatchException = null;
    
                try {
                    processedRequest = checkMultipart(request);
                    multipartRequestParsed = (processedRequest != request);
    
                    // Determine handler for the current request.
                    mappedHandler = getHandler(processedRequest);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        noHandlerFound(processedRequest, response);
                        return;
                    }
    
                    // Determine handler adapter for the current request.
                    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
                    // Process last-modified header, if supported by the handler.
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (logger.isDebugEnabled()) {
                            logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }
                        if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }
    
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
    
                    // Actually invoke the handler.
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }
    
                    applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                }
                catch (Exception ex) {
                    dispatchException = ex;
                }
                processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
            }
            catch (Exception ex) {
                triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
            }
            catch (Error err) {
                triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
            }
            finally {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    // Instead of postHandle and afterCompletion
                    if (mappedHandler != null) {
                        mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                    }
                }
                else {
                    // Clean up any resources used by a multipart request.
                    if (multipartRequestParsed) {
                        cleanupMultipart(processedRequest);
                    }
                }
            }
        }
    

    获取Handler

    根据Request获取Handler

    // Determine handler for the current request.
                    mappedHandler = getHandler(processedRequest);
    

    查看getHandler方法:

    
        /**
         * Return the HandlerExecutionChain for this request.
         * <p>Tries all handler mappings in order.
         * @param request current HTTP request
         * @return the HandlerExecutionChain, or {@code null} if no handler could be found
         */
        protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
            for (HandlerMapping hm : this.handlerMappings) {
                if (logger.isTraceEnabled()) {
                    logger.trace(
                            "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
                }
                HandlerExecutionChain handler = hm.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
            return null;
        }
    

    流程大概是:
    遍历类的handlerMappings域,使用HandlerMapping的getHandler方法获取HandlerExecutionChain,其中HandlerExecutionChain包含了handler以及一些列的Interceptor,如果结果不为空,返回该HandlerExecutionChain。


    HandlerExecutionChain

    handler是Object类型,后续的文章会分析为什么是Object类型。

    调用Interceptor的preHandler方法

        if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
    
                    // Actually invoke the handler.
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }
    
                    applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
    

    上一篇文章介绍了Interceptor的使用,基本上是写preHandler的实现。
    点开applyPostHandler方法:

        /**
         * Apply preHandle methods of registered interceptors.
         * @return {@code true} if the execution chain should proceed with the
         * next interceptor or the handler itself. Else, DispatcherServlet assumes
         * that this interceptor has already dealt with the response itself.
         */
        boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
            HandlerInterceptor[] interceptors = getInterceptors();
            if (!ObjectUtils.isEmpty(interceptors)) {
                for (int i = 0; i < interceptors.length; i++) {
                    HandlerInterceptor interceptor = interceptors[i];
                    if (!interceptor.preHandle(request, response, this.handler)) {
                        triggerAfterCompletion(request, response, null);
                        return false;
                    }
                    this.interceptorIndex = i;
                }
            }
            return true;
        }
    

    可见先获取HandlerExecutionChain的所有interceptor,遍历interceptor调用其preHandler方法。

    调用handler方法

       // Determine handler adapter for the current request.
                   HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    

    前面根据Object类型的handler获取了实际执行handle方法的HandlerAdapter。
    获取过程如下:

        /**
         * Return the HandlerAdapter for this handler object.
         * @param handler the handler object to find an adapter for
         * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
         */
        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;
                }
            }
            throw new ServletException("No adapter for handler [" + handler +
                    "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
        }
    

    可见也是从类的handerAdapter列表遍历,获取HanderAdapter。

    调用postHandler方法

    根据调用preHandler方式猜测,也是获取ExecutionChain中的interceptor列表,遍历调用postHandler方法。

        /**
         * Apply postHandle methods of registered interceptors.
         */
        void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
            HandlerInterceptor[] interceptors = getInterceptors();
            if (!ObjectUtils.isEmpty(interceptors)) {
                for (int i = interceptors.length - 1; i >= 0; i--) {
                    HandlerInterceptor interceptor = interceptors[i];
                    interceptor.postHandle(request, response, this.handler, mv);
                }
            }
        }
    

    postHandler方法的调用顺序与preHandler是刚好相反的,也就是如果interceoptor的preHandler方法如果是第一个执行的,那么其postHandler方法会最后一步执行。

    以上就是DispatchServlet源码分析,大致清楚了处理流程。

    后续文章会详细介绍HandlerApdater,HandlerMapping,HandlerExecutionChain的实现。

    相关文章

      网友评论

          本文标题:DispatchServlet源码分析

          本文链接:https://www.haomeiwen.com/subject/zpfogttx.html