二、SpringMVC的请求处理过程

上一章讲了SpringMVC的启动过程,包括DispatcherServlet的启动与spring的启动。这一章我们在SpringMVC已经启动的基础上,讲一个request是如何接受与处理的。

2.1、请求调用顺序

FrameworkServlet.service()
    └FrameworkServlet.processRequest(request, response);
        └DispatcherServlet.doService(request, response);
            └DispatcherServlet.doDispatch(request, response);
                ├HandlerExecutionChain mappedHandler=getHandler(request, false)
                │    │    //SpringMVC中配置了很多handlerMapping,按顺序逐个调用
                │    │    //如果某handlerMapping找到了Handler,则立刻返回
                │    │    //一般来说,handlerMappings的顺序是:
                │    │    //1、RequestMappingHandlerMapping//负责url到Handler名称映射
                │    │    //2、BeanNameUrlHandlerMapping//负责url到Handler名称映射
                │    │    //3、SimpleUrlHandlerMapping//负责url到Handler名称映射
                │    └HandlerExecutionChain handler = handlerMappings.getHandler(request);
                │        │    //以RequestMappingHandlerMapping为例
                │        └RequestMappingHandlerMapping.getHandler(request)
                │            └AbstractHandlerMapping.getHandler(request)
                │                ├Object handler = getHandlerInternal(request);
                │                │    └HandlerMethod hm = AbstractHandlerMethodMapping.getHandlerInternal(request);
                │                │        ├String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
                │                │        └HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
                │                │                └AbstractHandlerMethodMapping.lookupHandlerMethod(lookupPath, request);
                │                └getHandlerExecutionChain(handler, request);
                │                    ├for (MappedInterceptor mappedInterceptor : mappedInterceptors) 
                │                    └chain.addInterceptor(mappedInterceptor.getInterceptor());
                │                    //此步骤给handler增加interceptor
                │                    //从此处可知springMVC的每次request请求都会动态组装HandlerExecutionChain
                │
                ├HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
                │    │//此步骤从handlerAdapters获取一个support支持当前handler的Adapters
                │    └for (HandlerAdapter ha : this.handlerAdapters)if (ha.supports(handler))return ha;
                │        │//以RequestMappingHandlerAdapter为例
                │        └RequestMappingHandlerAdapter.supports(handler)
                │            └AbstractHandlerMethodAdapter.supports(handler)
                │                └return return handler instanceof HandlerMethod//根据上文可知handler为HandlerMethod,此处为true
                │
                ├mappedHandler.applyPreHandle(processedRequest, response)
                │    ├HandlerInterceptor[] interceptors = getInterceptors()
                │    └for(HandlerInterceptor h : interceptors)h.preHandle(request, response, this.handler)
                │
                ├ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());    
                │    └RequestMappingHandlerAdapter.handle(request, response, mappedHandler.getHandler());    
                │        └AbstractHandlerMethodAdapter.handle(request, response, mappedHandler.getHandler());    
                │            └RequestMappingHandlerAdapter.handleInternal(request, response, (HandlerMethod) handler);
                │                ├checkAndPrepare前处理:session过期,session检查等
                │                └invokeHandleMethod(request, response, handlerMethod);
                │                    ├ServletWebRequest webRequest = new ServletWebRequest(request, response);
                │                    ├ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory);
                │                    ├ModelAndViewContainer mavContainer = new ModelAndViewContainer();
                │                    ├requestMappingMethod.invokeAndHandle(webRequest, mavContainer);
                │                    │    └ServletInvocableHandlerMethod.invokeAndHandle(webRequest, mavContainer);
                │                    │        ├Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
                │                    │        │    ├Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
                │                    │        │    └return InvocableHandlerMethod.invoke(args);
                │                    │        │        └return getBridgedMethod().invoke(getBean(), args);//调用真正的Controller中的@RequestMapping注解的方法
                │                    │        │
                │                    │        └returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
                │                    │            │//是一个数组的包装类new HandlerMethodReturnValueHandlerComposite().addHandlers(getDefaultReturnValueHandlers());
                │                    │            │//在getDefaultReturnValueHandlers()中返回的是一个List<HandlerMethodReturnValueHandler>
                │                    │            │//例如ModelAndViewMethodReturnValueHandler、ViewNameMethodReturnValueHandler、ModelMethodProcessor、ViewMethodReturnValueHandler
                │                    │            │//最常用的是前两个ModeAndView处理器和ViewName处理器,分别对应方法返回ModelAndView和String两种情况。只要命中一个,则不再执行下一个handler
                │                    │            │//以下以ModelAndViewMethodReturnValueHandler为例
                │                    │            ├mavContainer.setViewName(viewName);
                │                    │            └mavContainer.setRedirectModelScenario(true);
                │                    │
                │                    └return getModelAndView(mavContainer, modelFactory, webRequest);
                │                        └ModelAndView mav = new ModelAndView(mavContainer.getViewName(), mavContainer.getModel());
                │
                ├mappedHandler.applyPostHandle(processedRequest, response, mv);
                │    ├HandlerInterceptor[] interceptors = getInterceptors()
                │    └for(HandlerInterceptor h : interceptors)h.postHandle(request, response, mv)
                └processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);    
                    ├render(mv, request, response);
                    │    ├View view = viewResolver.resolveViewName(mv.getViewName(), locale);//此处viewResolover常用的是FreeMarkerViewResolver,返回FreeMarkerView
                    │    └view.render(mv.getModelInternal(), request, response);
                    │        ├Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
                    │        ├prepareResponse(request, response);
                    │        └renderMergedOutputModel(mergedModel, request, response);
                    │            └FreeMarkerView.doRender(model, request, response);
                    │                └template.process(model, response.getWriter());//给用户输出内容
                    │    
                    └mappedHandler.triggerAfterCompletion(request, response, null);
                        ├HandlerInterceptor[] interceptors = getInterceptors()
                        └for(HandlerInterceptor h : interceptors)h.afterCompletion(request, response, ex)

2.2、请求调用总结

在DispatcherServlet的调用过程中

1、根据系统初始化出的HandlrMapping解析URL,获取到具体的HandlerMethod

2、对HandlerMethod增加interceptor,最终生成HandlerExecutionChain

3、根据handler生成HandlerAdapter,在HandlerAdapter内具有更高级的操作

4、执行interceptors的prehandler

5、通过handlerAdapter处理session处理,请求封装,调用实际方法,返回结果封装,返回结果转换为ModelAndView

6、执行interceptors的posthandler,因为在第五步已经将返回结果封装为ModelAndView,因此postHandle的参数为ModelAndView

7、通过viewResolver获取到view,进而通过view.render把响应结果发送给客户端

8、调用interceptor的afterCompletion方法。


以上即是SpringMVC的请求调用过程,其细节上还有很多可追究的地方,不再一一讨论。