Spring MVC的请求处理流程

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值