美文网首页
SpringMVC底层实现记录

SpringMVC底层实现记录

作者: GentleWind | 来源:发表于2018-05-31 20:46 被阅读0次

    我理解的SpringMVC实现如下图所示:

    springMVC流程

    浏览器发送HTTP请求后,DispatcherServlet主要做了几个步骤的处理:

    • 根据request调用HandlerMapping找到Handler(返回HandlerExecutionChain)

    • 根据Handler找到对应的HandlerAdapter(处理适配器)

    • 用HandlerAdapter处理Handler (返回ModelAndView)

    • 调用processDispatchResult方法处理上面处理之后的结果(包含找到view并解析)

      1. ViewRolver处理ModleAndView的view
      2. view渲染model的请求,调用render方法

    贴上DispatcherServlet的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.(根据request找到handler)
                    mappedHandler = getHandler(processedRequest);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        noHandlerFound(processedRequest, response);
                        return;
                    }
    
                    // Determine handler adapter for the current request.(根据handler找到HandlerAdapter)
                    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.(HandlerAdapter使用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;
                }
                catch (Throwable err) {
                    // As of 4.3, we're processing Errors thrown from handler methods as well,
                    // making them available for @ExceptionHandler methods and other scenarios.
                    dispatchException = new NestedServletException("Handler dispatch failed", err);
                }
                //处理返回结果。包括处理异常、渲染界面、发出完成通知出发Interceptor的afterCompletion
                processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
            }
            catch (Exception ex) {
                triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
            }
            catch (Throwable err) {
                triggerAfterCompletion(processedRequest, response, mappedHandler,
                        new NestedServletException("Handler processing failed", 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);
                    }
                }
            }
        }
    

    总结:

    SpringMVC的DispatcherServlet顶层设计的比较好,主要调用doService()设置相关属性后,调用doDispatch(),然后渲染视图传回前端。

    相关文章

      网友评论

          本文标题:SpringMVC底层实现记录

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