美文网首页spring
Spring MVC源码解读三

Spring MVC源码解读三

作者: 测试你个头 | 来源:发表于2017-02-24 11:25 被阅读0次

    接上一篇:Spring MVC源码解析二

    • spring mvc请求分发链路:
      通过时序图可以看到,servlet对request请求进行拦截后,先后调用了FrameworkServlet的processRequest()、doService(),最终调用了DispatcherServlet的doDispatch()方法
      doDispatch的源码:
    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;
                    }
    
                    try {
                        // Actually invoke the handler.
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    }
                    finally {
                        if (asyncManager.isConcurrentHandlingStarted()) {
                            return;
                        }
                    }
    
                    applyDefaultViewName(request, 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
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                    return;
                }
                // Clean up any resources used by a multipart request.
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    

    核心处理如下:

    mappedHandler  = getHandler()  //get handler by url handlermapping
    ha = getHandlerAdapter()  //get handleradapter
    ha.handle()  //通过adapter调用handler的处理方法
    processDispatchResult()  //处理doDispatch的处理结果
    

    分别查看源码:
    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;
        }
    

    1、getHandler()主要就是通过this.handlerMappings中的HandlerMapping实例来对具体request映射一个handler(spring mvc中的controller类和controller类中的具体方法) 2、如果看过[spring mvc源码解析二]中对于this.handlerMappings初始化的解读,便知道HandlerMapping的具体实现有3个: 1.RequestMappingHandlerMapping 2.BeanNameUrlHandlerMapping 3.SimpleUrlHandlerMapping 3、spring mvc中正是通过这3个类实现了重要的request和controller的mapping

    getHandlerAdapter从this.handlerAdapters中匹配获取对应的handlerAdapter,且获取对应的handler

        /**
         * 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");
        }
    

    handle()是HandleAdapter中定义的接口,具体的实现类有很多,在DispatcherServlet中具体使用哪个实现,是由上一步调用的getHandlerAdapter决定的,handle()接口的具体作用如接口注释描述:使用指定的handler来处理http请求

        /**
         * Use the given handler to handle this request.
         * The workflow that is required may vary widely.
         * @param request current HTTP request
         * @param response current HTTP response
         * @param handler handler to use. This object must have previously been passed
         * to the {@code supports} method of this interface, which must have
         * returned {@code true}.
         * @throws Exception in case of errors
         * @return ModelAndView object with the name of the view and the required
         * model data, or {@code null} if the request has been handled directly
         */
        ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    

    相关文章

      网友评论

        本文标题:Spring MVC源码解读三

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