SpringMVC解析

1 SpringMVC执行流程

image.png

简单流程:
1 前端发起web请求
2 dispatchServlet收到请求,转发到对应的controller
3 controller处理业务逻辑,将处理结果或页面返回给dispatchServlet
4 dispatchServlet再将结果转发到视图解析器view
5 视图解析器解析结果返回到web端

image.png

详细流程:
1 前端发起web请求
2 dispatchServlet收到请求,基于handlerMapping地址映射,找到对应的handler(控制器,即controller)
3 基于handler找对应的handlerAdapter,调用handler方法返回ModelaAndView
4 利用viewResolver,通过返回的ModelAndView找到对应的view视图解析器
5 解析视图,response返回结果到web端

2 springmvc组件

2.1 HandlerMapping

HandlerMapping即url映射,根据web端的地址找到处理该请求的控制器,就是HandlerMapping做的事。通过HandlerMapping继承树,可以发现有三个子类。

  • SimpleUrlHandlerMapping:需手动配置映射关系。


        
            
                simpleControl
            
        

  • BeanNameUrlHandlerMapping:根据配置的beanname自动从映射关系中找到controller。

  • RequestMappingHandlerMapping:我们工作中最常用的,通过@RequestMapping映射。这里不做举例。

springmvc中默认配置的是BeanNameUrlHandlerMapping。前两个是类映射,RequestMappingHandlerMapping是方法映射。

注意:
1 如果自己配置了HandlerMapping,那么默认的就不生效了
2 可以配置多个HandlerMapping。如果配置了多个HandlerMapping,且urlname一样,那么会根据HandlerMapping的order排序值选择HandlerMapping

2.2 HandlerAdapter

HandlerAdapter即适配器,每个Handler都对应一个适配器来调用handler。


HandlerAdapter.jpg

springmvc默认配置了SimpleControllerHandlerAdapter和HttpRequestHandlerAdapter

2.3 Handler

Handler可以理解为controller,即控制器,用于处理业务逻辑,返回ModelAndView。Handler具体实现有以下四种。

  • Controller
public class TestController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView modelAndView = new ModelAndView("userView");
        modelAndView.addObject("name","小明");
        return modelAndView;
    }
}
  • HttpRequestHandler
public class TestHttpRequestHandler implements HttpRequestHandler {
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("666");
    }
}
  • HttpServlet
public class TestHttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("666");
    }
}

在使用HttpServlet时,必须配置一个对应的适配器。因为springmvc默认配置的适配器是上面两个handler对应的适配器。

  • @RequestMapping注解(常用的,此处不举例了)
2.4 ViewResolver

ViewResolver是用来管理视图解析器view的。ViewResolver中只有一个方法。根据viewName找到view。

View resolveViewName(String viewName, Locale locale) throws Exception;

ViewResolver有三个常用的实现类:

  • BeanNameViewResolver 根据名称找到对应的View


public class TestController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView modelAndView = new ModelAndView("myView");
        modelAndView.addObject("name","小明");
        return modelAndView;
    }
}
public class MyView implements View {

    public String getContentType() {
        return null;
    }

    public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
          //model.get("name")就是controller中设置的属性
        response.getWriter().println(model.get("name"));
    }
}
  • InternalResourceViewResolver
    这是springmvc默认配置的ViewResolver,也可手动修改配置,添加前后缀。

        
        
        

  • AbstractTemplateViewResolver
    包括FreeMarkerViewResolver和GroovyMarkupViewResolver。没怎么用过,这里不做举例了。
2.5 View

View就是视图解析器,作用是对ModelAndView中的数据解析,通过Response返回到web端。实现View接口,重写render方法,就能自定义一个视图解析器

void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception;
2.6 HandlerExceptionResolver

HandlerExceptionResolver即异常处理器,用于处理整个springmvc执行流程中出现的异常。

2.6.1 常用的有三个异常处理器:

springmvc默认配置的是DefaultHandlerExceptionResolver和ResponseStatusExceptionResolver

  • DefaultHandlerExceptionResolver
    根据传入的Exception异常参数判断是哪种具体的异常来进行相应的处理返回。‘

  • ResponseStatusExceptionResolver
    根据异常类型上面的@ResponseStatus注解的code和reason参数,
    返回对应的错误信息

@ResponseStatus(code = HttpStatus.GATEWAY_TIMEOUT, reason = "访问超时")
public class ResponseStatusException extends RuntimeException {
    public ResponseStatusException() {
    }

    public ResponseStatusException(String message) {
        super(message);
    }
}
public class TestController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView modelAndView = new ModelAndView("myView");
        //这边强制抛出一个ResponseStatusException,测试用
        if(true){
            throw new ResponseStatusException();
        }

        modelAndView.addObject("name","小明");
        return modelAndView;
    }
}

虽然springmvc默认配置了这个ResponseStatusExceptionResolver,但还是要自己配置一下,因为这里自定义了一个异常,所以默认的配置无法生效。

这时,web端访问这个TestController对应的url,就会出现504异常GATEWAY_TIMEOUT

  • SimpleMappingExceptionResolver
    将异常和异常处理页面绑定,如果出现异常就跳转到绑定页面
    
        
        
        
        
        
        
            
                
                
            
        
    
2.6.2 自定义异常处理器

实现HandlerExceptionResolver接口,并重写resolveException方法。

public class SimpleExceptionHandle implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("message", ex.getMessage());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        //将异常信息通过打印流打印到输出流out中
        ex.printStackTrace(new PrintStream(out, true));
        modelAndView.addObject("stack", out.toString());
        return modelAndView;
    }
}

意思就是获取异常信息,打印到输出流中,并放入ModelAndView,通过视图解析器返回到error.jsp页面显示错误信息。

    

配置自定义异常处理器。

2.7 HandlerInterceptor

HandlerInterceptor即拦截器。有以下三个方法

  • preHandle 在调用handler方法之前调用。
  • postHandle 在成功调用handler方法后调用。
  • afterCompletion 在调用handler方法之后调用。即使在调用handler方法时出现异常,也会调用afterCompletion。如果没有异常,则顺序在postHandle之后。

自定义拦截器示例:

public class SimpleHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

配置拦截器:


        
            
            
        

可以定义多个拦截器,形成一个拦截器链,比如在handler方法之前会依此遍历拦截器链,依此调用所有拦截器的preHandle方法。

注:异常处理器不是所有配置的都执行。如果在异常处理器的resolveException中返回ModelAndView,表示异常已经被这个异常处理器处理了;如果返回null,表示没有处理,会去找下一个异常处理器处理。
而拦截器则是所有配置的拦截器都会执行。

3 springmvc执行流程源码解析

springmvc执行流程的核心就是DispatcherServlet的doDispatch方法。
下面就拿@RequestMapping方式来解析。

1 注册handler

HandlerMapping可以根据url来找到对应的handler,那么这些对应关系是怎么注册的呢?

protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
          //校验
        Assert.notNull(urlPath, "URL path must not be null");
        Assert.notNull(handler, "Handler object must not be null");
        Object resolvedHandler = handler;

        // 如果是懒加载的,就存handler的名字
        if (!this.lazyInitHandlers && handler instanceof String) {
            String handlerName = (String) handler;
            if (getApplicationContext().isSingleton(handlerName)) {
                          // 从spring容器中根据beanname获取bean
                resolvedHandler = getApplicationContext().getBean(handlerName);
            }
        }
            // url跟handler对应关系保存在handerMap中
        Object mappedHandler = this.handlerMap.get(urlPath);
        if (mappedHandler != null) {
            if (mappedHandler != resolvedHandler) {
                throw new IllegalStateException(
                        "Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
                        "]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
            }
        }
        else {
                // 如果url是/,那么设置这个handler是根handler
            if (urlPath.equals("/")) {
                if (logger.isInfoEnabled()) {
                    logger.info("Root mapping to " + getHandlerDescription(handler));
                }
                setRootHandler(resolvedHandler);
            }
      //如果url是/*,那么设置这个handler为默认的handler,所有找不到对应关系的都找这个handler
            else if (urlPath.equals("/*")) {
                if (logger.isInfoEnabled()) {
                    logger.info("Default mapping to " + getHandlerDescription(handler));
                }
                setDefaultHandler(resolvedHandler);
            }
            else {
                        // 将url作为key,handler作为value,存在handlerMap中
                this.handlerMap.put(urlPath, resolvedHandler);
                if (logger.isInfoEnabled()) {
                    logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
                }
            }
        }
    }
2 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);

                // 获取handler
                mappedHandler = getHandler(processedRequest);
                   //如果没有获取到,抛错
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // 获取处理这个handler的适配器
                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;
                    }
                }
                  // 执行拦截器的preHandle方法
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // 通过适配器调用handle方法处理业务逻辑
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                      //如果没指定viewName,设置一个默认的viewName
                applyDefaultViewName(processedRequest, mv);
                    //执行拦截器的postHandle方法
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                            //上面所有的异常都只是抛出,没处理,这里才是捕获异常
                dispatchException = ex;
            }
            catch (Throwable err) {
                // err错误
                dispatchException = new NestedServletException("Handler dispatch failed", err);
            }
                // 视图解析器处理modelAndView,通过response返回数据给web端
            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()) {
                // 不管是否出错,都会最后执行拦截器的afterCompletion方法
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
            else {
                // Clean up any resources used by a multipart request.
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    }

执行过程:
1 根据HandlerMapping获取handler链
2 根据handler获取对应的适配器
3 执行拦截器的preHandle方法
4 通过适配器,调用handle方法处理业务逻辑
5 如果没有异常,执行拦截器的postHandle方法
6 不管有没有异常,执行拦截器的afterCompletion方法
7 视图解析器处理modelAndView,通过response返回数据给web端

3.2.1 getHandler

获取handler链

    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
          //遍历1中的handlerMapping,找handler
        for (HandlerMapping hm : this.handlerMappings) {
            if (logger.isTraceEnabled()) {
                logger.trace(
                        "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
            }
              //获取HandlerExecutionChain,并不是返回Handler,因为里面还包含拦截器链 
            HandlerExecutionChain handler = hm.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
        return null;
    }
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
          // 获取handler,因为是@RequestMaping,所以这里获取HandlerMethod
        Object handler = getHandlerInternal(request);
        if (handler == null) {
            handler = getDefaultHandler();
        }
        if (handler == null) {
            return null;
        }
        // 如果是懒加载,那么根据之前注册时存的handlerName获取handler
        if (handler instanceof String) {
            String handlerName = (String) handler;
            handler = getApplicationContext().getBean(handlerName);
        }
                  // 将handler和所有拦截器封装成一个handler链
        HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
        if (CorsUtils.isCorsRequest(request)) {
            CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
            CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
            CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
            executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
        }
        return executionChain;
    }
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
            // 获取url路径
        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        if (logger.isDebugEnabled()) {
            logger.debug("Looking up handler method for path " + lookupPath);
        }
        this.mappingRegistry.acquireReadLock();
        try {
              // 获取执行业务逻辑的方法
            HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
            if (logger.isDebugEnabled()) {
                if (handlerMethod != null) {
                    logger.debug("Returning handler method [" + handlerMethod + "]");
                }
                else {
                    logger.debug("Did not find handler method for [" + lookupPath + "]");
                }
            }
            return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
        }
        finally {
            this.mappingRegistry.releaseReadLock();
        }
    }
3.2.2 getHandlerAdapter

获取handler对应的适配器

    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");
    }
3.2.3 applyPreHandle

调用所有拦截器的preHandle方法

    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = 0; i < interceptors.length; i++) {
                HandlerInterceptor interceptor = interceptors[i];
                  // 如果前置拦截返回false,就调用后置拦截,然后直接返回到web端,不执行业务逻辑了
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);
                    return false;
                }
                this.interceptorIndex = i;
            }
        }
        return true;
    }
3.2.4 handle

通过适配器调用handle方法,执行业务逻辑
因为这里是@RequestMapping,所以进入RequestMappingHandlerAdapter的invokeHandlerMethod方法

protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        try {
            WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
            ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
                // 设置一个方法执行器
            ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
              //设置参数处理器         invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
        //设置返回值处理器  invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
            invocableMethod.setDataBinderFactory(binderFactory);
        // 设置参数名字处理器,可以根据请求参数中名字,自动对应到handler的目标方法的参数名字 invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

            ModelAndViewContainer mavContainer = new ModelAndViewContainer();
            mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
            modelFactory.initModel(webRequest, mavContainer, invocableMethod);
            mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

            AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
            asyncWebRequest.setTimeout(this.asyncRequestTimeout);

            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
            asyncManager.setTaskExecutor(this.taskExecutor);
            asyncManager.setAsyncWebRequest(asyncWebRequest);
            asyncManager.registerCallableInterceptors(this.callableInterceptors);
            asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

            if (asyncManager.hasConcurrentResult()) {
                Object result = asyncManager.getConcurrentResult();
                mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
                asyncManager.clearConcurrentResult();
                if (logger.isDebugEnabled()) {
                    logger.debug("Found concurrent result value [" + result + "]");
                }
                invocableMethod = invocableMethod.wrapConcurrentResult(result);
            }
                  // 通过方法执行器调用方法,处理业务逻辑
            invocableMethod.invokeAndHandle(webRequest, mavContainer);
            if (asyncManager.isConcurrentHandlingStarted()) {
                return null;
            }

            return getModelAndView(mavContainer, modelFactory, webRequest);
        }
        finally {
            webRequest.requestCompleted();
        }
    }
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {
        // 执行目标方法
        Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
        setResponseStatus(webRequest);

        if (returnValue == null) {
            if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
                mavContainer.setRequestHandled(true);
                return;
            }
        }
        else if (StringUtils.hasText(getResponseStatusReason())) {
            mavContainer.setRequestHandled(true);
            return;
        }

        mavContainer.setRequestHandled(false);
        try {
            this.returnValueHandlers.handleReturnValue(
                    returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
        }
        catch (Exception ex) {
            if (logger.isTraceEnabled()) {
                logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
            }
            throw ex;
        }
    }
    public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {
        // 获取方法中的参数
        Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
                    "' with arguments " + Arrays.toString(args));
        }
        // 通过反射调用目标方法,获取返回结果ModelAndView
        Object returnValue = doInvoke(args);
        if (logger.isTraceEnabled()) {
            logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
                    "] returned [" + returnValue + "]");
        }
        return returnValue;
    }
3.2.5 applyPostHandle

执行拦截器的中间方法,由于在执行业务方法之后,如果出现异常,拦截器中间方法并不会执行

    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = interceptors.length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }
    }
3.2.6 applyAfterConcurrentHandlingStarted

此方法在finally中,所以不管有没有异常,都会执行这个拦截器的后置方法

3.2.7 processDispatchResult

捕获业务逻辑执行中的异常并在此统一处理,然后视图解析器处理ModelAndView,封装数据,返回给web端

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
            HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {

        boolean errorView = false;

        if (exception != null) {
            if (exception instanceof ModelAndViewDefiningException) {
                logger.debug("ModelAndViewDefiningException encountered", exception);
                mv = ((ModelAndViewDefiningException) exception).getModelAndView();
            }
            else {
                Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
                //处理异常,封装到ModelAndView中
                mv = processHandlerException(request, response, handler, exception);
                errorView = (mv != null);
            }
        }

        // 视图解析器处理ModelAndView
        if (mv != null && !mv.wasCleared()) {
            render(mv, request, response);
            if (errorView) {
                WebUtils.clearErrorRequestAttributes(request);
            }
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
                        "': assuming HandlerAdapter completed request handling");
            }
        }

        if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
            // Concurrent handling started during a forward
            return;
        }

        if (mappedHandler != null) {
            mappedHandler.triggerAfterCompletion(request, response, null);
        }
    }
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // Determine locale for request and apply it to the response.
        Locale locale = this.localeResolver.resolveLocale(request);
        response.setLocale(locale);

        View view;
        if (mv.isReference()) {
            // 根据viewName从ViewResolver中获取视图解析器
            view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
            if (view == null) {
                throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
                        "' in servlet with name '" + getServletName() + "'");
            }
        }
        else {
            // No need to lookup: the ModelAndView object contains the actual View object.
            view = mv.getView();
            if (view == null) {
                throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
                        "View object in servlet with name '" + getServletName() + "'");
            }
        }

        // Delegate to the View object for rendering.
        if (logger.isDebugEnabled()) {
            logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
        }
        try {
            if (mv.getStatus() != null) {
                response.setStatus(mv.getStatus().value());
            }
                  // 调用view的render方法,处理数据,通过response返回
            view.render(mv.getModelInternal(), request, response);
        }
        catch (Exception ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +
                        getServletName() + "'", ex);
            }
            throw ex;
        }
    }

至此SpringMVC的执行流程解析完毕。

你可能感兴趣的:(SpringMVC解析)