Spring MVC的请求处理流程

  1. DispatcherServlet的处理流程图
  2. 核心处理流程步骤
  3. DispatcherServlet 的初始化过程

DispatcherServlet的处理流程图

DispatcherServlet的处理流程

核心处理流程步骤

  1. 检测是否是文件上传, 并处理
  2. 根据 Request 获取 HandlerExecutionChain
    2-1: 首先解析 Request 的请求的Path
    2-2: 根据 Path 在返回 HanlderMethod
    2-3: 将 HanlderMethod + HandlerInterceptor 包装成 HandlerExecutionChain 返回.
  3. 执行Chain的preHanlde方法
  4. 根据Chain的HandlerMethod, 调用对应的Controller的method, 并返回ModelAndView对象(如果ModelAndView对象为null或者没有View, 那么直接使用默认实现值返回).
  5. 执行Chain的postHandle方法
  6. 根据vm返回值渲染页面
    6-1: 根据viewName解析View对象
    6-2: 根据view对象渲染页面
// 从代码中解读
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;

                try {
                    processedRequest = this.checkMultipart(request); // 步骤1
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest); // 步骤2
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                    if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 步骤3
                        return;
                    }

                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 步骤4 
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);  // 步骤5 
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException); //步骤6 
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

DispatcherServlet 的初始化过程

  1. initMultipartResolver: 文件上传处理器
    从容器中获取名为multipartResolver的Bean做该类型的组件, 没有则不拥有该类型组件
    默认实现: 没有默认实现

  2. initLocaleResolver: 国际化处理器
    从容器中获取名为localeResolver的Bean做该类型的组件, 没有则调用默认实现
    默认实现: org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

  3. initThemeResolver: 主题管理处理器 对应容器中的Bean是: themeResolver
    从容器中获取名为themeResolver的Bean做该类型的组件, 没有则调用默认实现
    默认实现: org.springframework.web.servlet.theme.FixedThemeResolver

  4. initHandlerMappings: 处理映射器 主要做url到处理类的映射
    如果 detectAllHandlerMappings = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HanlderMapping的Bean, 作为该类型组件
    否则 查找名称为handlerMapping的Bean, 作为该类型的组件
    如果都没有找到, 则调用默认实现
    默认实现:

     1. org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping()
     2. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
  5. initHandlerAdapters: 处理适配器 处理器的真正实现
    如果 detectAllHandlerAdapters = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
    否则 查找名称为handlerAdapter的Bean, 作为该类型的组件
    如果都没有找到, 则调用默认实现
    默认实现:

     1. org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
     2. org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
     3. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
  6. initHandlerExceptionResolvers: 异常处理器
    如果 detectAllHandlerExceptionResolvers = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
    否则 查找名称为handlerExceptionResolver的Bean, 作为该类型的组件
    如果都没有找到, 则调用默认实现
    默认实现:

     1. org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
     2. org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
     3. org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
  7. initRequestToViewNameTranslator: 视图名称翻译器
    查找名称为viewNameTranslator的Bean作为该类型的组件, 没有则调用默认实现
    默认实现: org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

  8. initViewResolvers: 视图解析器
    如果 detectAllViewResolvers = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
    否则 查找名称为viewResolver的Bean, 作为该类型的组件
    如果都没有找到, 则调用默认实现
    默认实现: org.springframework.web.servlet.view.InternalResourceViewResolver

  9. initFlashMapManager: 重定向数据管理器
    查找名称为flashMapManager的Bean作为该类型的组件, 没有则调用默认实现
    默认实现: org.springframework.web.servlet.support.SessionFlashMapManager


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 zhao4xi@126.com

文章标题:Spring MVC的请求处理流程

文章字数:990

本文作者:Zhaoxi

发布时间:2018-12-27, 15:11:12

最后更新:2019-09-21, 15:12:21

原始链接:http://zhao4xi.github.io/2018/12/27/Spring-MVC的请求处理流程/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录