通过DispatcherServlet源码分析SpringMVC执行流程

通过DispatcherServlet源码分析SpringMVC执行流程

前言:分析SpringMVC执行过程我们只需要关注DispatcherServlet的doDispatch()方法即可。SpringMVC的执行过程这里先简单的总结为以下几点,具体的可以看代码里面的注释。

  1. 前端发起请求进入DispatcherServlet的doDispatch()方法
  2. 调用HandlerMapping处理器映射器处理url,返回HandlerExecutionChain
  3. 通过mappedHandler获取HandlerAdapter
  4. HandlerAdapter处理器适配器找到具体的Controller的具体方法处理,方法处理完后返回ModelAndView
  5. 将ModelAndView传给ViewReslover视图解析器,返回View,根据返回的View渲染视图
  6. 前端展示渲染的页面

如果是Restful风格的Api,返回的是JSON数据,那么第4步返回的ModelAndView为null,后面的步骤就不会执行。其实返回JSON数据第4步处理完成之后就已经通过HttpServletResponse的OutputStream写出数据了。

具体请看代码里面的注释:


 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);
                    multipartRequestParsed = processedRequest != request;
                    // 1、调用HandlerMapping处理器映射器处理url,返回HandlerExecutionChain
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
                    // 2、通过mappedHandler获取HandlerAdapter
                    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 ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
                    // 3、HandlerAdapter处理器适配器找到具体的Controller的具体方法处理,方法处理完后返回ModelAndView
                    // 注: 如果添加了@ResponseBody或者@RestController返回的mv为null,直接通过HttpServletResponse的OutputStream响应json数据
                    // handle方法源码很复杂,这里就不展开说明了
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }
                // 具体实现processDispatchResult看下面代码
                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } 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);
            }

        }
    }


    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
        boolean errorView = false;
        if (exception != null) {
            if (exception instanceof ModelAndViewDefiningException) {
                this.logger.debug("ModelAndViewDefiningException encountered", exception);
                mv = ((ModelAndViewDefiningException)exception).getModelAndView();
            } else {
                Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
                mv = this.processHandlerException(request, response, handler, exception);
                errorView = mv != null;
            }
        }
        
        // 注:除了返回ModelAndView的方法外, 添加了@ResponseBody注解的方法或者@RestController下方法都不会进入下面方法
        // 无论是否添加@ResponseBody或者@RestController,只要返回ModelAndView都会执行this.render()方法
        if (mv != null && !mv.wasCleared()) {
        	// 4、将ModelAndView传给ViewReslover视图解析器,返回View,根据返回的View渲染视图;
            this.render(mv, request, response);
            if (errorView) {
                WebUtils.clearErrorRequestAttributes(request);
            }
        } else if (this.logger.isTraceEnabled()) {
            this.logger.trace("No view rendering, null ModelAndView returned.");
        }

        if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
            }

        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值