通过前面一章的分析,我们拿到了HandlerAdapter,然后我们开始进入它的实现类,执行
handle(HttpServletRequest request, HttpServletResponse response, Object handler)
发现其实际调用类为:RequestMappingHandlerAdapter,我们继续分析:
- handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod)
这个handlerMethod,就是前面我们最先拿到的HandlerExecutionChain中的handler。方法源码如下:
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// 请求会话不需要走同步代码块,我们直接分析invokeHandlerMethod
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
- mav = invokeHandlerMethod(request, response, handlerMethod);
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
....
....
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
这一块代码,我们分析invocableMethod.invokeAndHandle(webRequest, mavContainer)和getModelAndView(mavContainer, modelFactory, webRequest);
- invocableMethod.invokeAndHandle(webRequest, mavContainer)
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//1.执行目标方法,然后返回 返回值 。最终调用 this.getBridgedMethod().invoke(this.getBean(), args) 然后通过反射机制,获取执行请求的返回值
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
setResponseStatus(webRequest);
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
//2.处理返回结果returnValue
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
- getModelAndView(mavContainer, modelFactory, webRequest);
@Nullable
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
modelFactory.updateModel(webRequest, mavContainer);
if (mavContainer.isRequestHandled()) {
return null;
}
ModelMap model = mavContainer.getModel();
//在这边,我们能看见,modelAndView是通过代码自己new出来的,传入了三个参数,viewName,model和status,这三个参数都是通过mavContainer来获取的 第一个参数:viewName mavContainer.getViewName()方法返回viewName,如果view是String类型的实例,那么返回view,否则返回null
//第二个参数:model mavContainer.getModel(), 得到defaultModel或者是redirectModel,之前在invokeHandlerMethod创建modelFactory的时候就设置了两个参数的值
//第三个参数:status mavContainer.getStatus(),该方法返回的值的类型是HttpStatus,也就是状态码
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
}
return mav;
}
- 自此dispatcherServlet中的mv = ha.handle(processedRequest, response, mappedHandler.getHandler());就执行完毕了。总起来说,在这个方法中,执行了反射执行了目标方法,并获取返回值,然后根据mavContainer的属性,来返回mav是null还是ModelAndView。最后呢,就是执行拦截器中的PostHandle。当报错的时候,执行拦截器中的afterCompletion
到此,springmvc的大概源码我们就分析完了。有些不到位的地方,望能指出,一起学习。。