Spring MVC 核心调用流程( 四 )


前置过滤器

返回主流程 , 进入 applyPreHandle方法 , 前置过滤器
所在类:org.springframework.web.servlet. DispatcherServlet
/** * TODO :调用所有的 HandlerInterceptor 拦截器并调用其 preHandler方法 */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];// 分别调用拦截器的 preHandle 方法if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}// 如果失败 , 记录最后一次拦截器的位置 , 倒序释放this.interceptorIndex = i;}}return true;}
返回主流程 , 进入 handle方法 , 调用具体 Controller的方法
最终会进入 AbstractHandlerMethodAdapter的 handle方法 , 
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return handleInternal(request, response, (HandlerMethod) handler);}
进入 handleInternal方法 , 
所在类:org.springframework.web.servlet.mvc.method.annotation. RequestMappingHandlerAdapter
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// 执行 HandlerMethod , 返回 ModelAndViewmav = invokeHandlerMethod(request, response, handlerMethod);}}else {// No synchronization on session demanded at all...// 执行 HandlerMethod , 返回 ModelAndViewmav = invokeHandlerMethod(request, response, handlerMethod);}if (!response.containsHeader(HEADER_CACHE_CONTROL)) {if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);}else {prepareResponse(response);}}return mav;}
进入 invokeHandlerMethod方法 , 
所在类:org.springframework.web.servlet.mvc.method.annotation. RequestMappingHandlerAdapter
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ServletWebRequest webRequest = new ServletWebRequest(request, response);try {// 获取数据绑定工厂@InitBinder注解支持 , WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);// Model工厂,收集了@ModelAttribute注解的方法ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);//可调用的方法对象ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);if (this.argumentResolvers != null) {//设置参数解析器invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);}if (this.returnValueHandlers != null) {// 设置返回值解析器invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);}// 设置参数绑定工厂invocableMethod.setDataBinderFactory(binderFactory);// 设置参数名称解析类invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);ModelAndViewContainer mavContainer = new ModelAndViewContainer();mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));// 调用有 @ModelAttribute注解的方法 。每次请求都会调用有 @ModelAttribute注解的方法//把 @ModelAttribute注解的方法的返回值存储到 ModelAndViewContainer对象的 map中了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();LogFormatUtils.traceDebug(logger, traceOn -> {String formatted = LogFormatUtils.formatValue(result, !traceOn);return "Resume with async result [" + formatted + "]";});invocableMethod = invocableMethod.wrapConcurrentResult(result);}// Controller方法调用 , 重点看看invocableMethod.invokeAndHandle(webRequest, mavContainer);if (asyncManager.isConcurrentHandlingStarted()) {return null;}return getModelAndView(mavContainer, modelFactory, webRequest);}finally {webRequest.requestCompleted();}}


推荐阅读