直接进入主题,当我们执行一条请求的时候,是会进入到org.springframework.web.servlet.DispatcherServlet类的doDispatch方法中




如果有对应的handle,那么此时就要获取对应的HandlerAdapter

接下来看下这行代码


接下来看下下面这个方法





这里标记了二个方法,
Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);

接下来看下处理返回值的方法
this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);

首先看下下面这个方法
HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);

我们看下如果没有加@ResponseBody注解是返回一个怎么样的HandlerMethodReturnValueHandler

返回的是ViewNameMethodReturnValueHandle,如果添加了@ResponseBody返回的是不一样的
接下来看下下面这个方法
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
进入到org.springframework.web.servlet.mvc.method.annotation.ViewNameMethodReturnValueHandler类中的handleReturnValue方法


这个viewName就是我们方法返回的页面的名称,在这里将这个值设置好,设置好之后就回到org.springframework.web.servlet.DispatcherServlet的doDispatch()方法

刚刚我们是分析了下面这个方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
接下来分析下
this.applyDefaultViewName(processedRequest, mv);
这个方法有个mv的参数,看下值是什么

其实就是ModelAndView对象,并且将我们要返回的页面的名称设置进去,刚刚解析过了是怎么设置的,然后进入这个方法

这个方法是说mv这个对象不为空,但是没有返回的具体页面,那么就设置成默认的返回页面


看出来这是执行拦截器的后置处理方法的,接下来看下doDispatch()最后一个方法,如下图



最后一直进入到org.springframework.web.servlet.view.InternalResourceView类的renderMergedOutputModel()方法

最后执行RequestDispatcher.forward()来实现页面跳转。这是没有@ResponseBody注解的,接下里看下有@ResponseBody注解时候是怎么实现的。还记得之前处理返回结果的方法嘛??



if(handler.supportsReturnType(returnType))

我们继续看下下面这个方法
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
它是执行了org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor类中的handleReturnValue方法

接下来会进入到org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor类中的下面这个方法





最后用OutPutStream.write()将我们的结果返回