springMvc之doDispatch

On a front-end summary of overall controller of the initial word DispatcherServlet SpringMvc the process, in the final analysis to DispatcherServlet.doDispatch () method herein, this is the main core SpringMvc the overall flow of analysis, the doDispatch () method of processing the request.

doDispatch holistic approach Source:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   HttpServletRequest processedRequest = request;
  //HandlerExecutionChain(处理器执行链)保存需要执行的处理器和拦截器
   HandlerExecutionChain mappedHandler = null;
   boolean multipartRequestParsed = false;
   //异步请求管理器
   WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

   try {
      ModelAndView mv = null;
      Exception dispatchException = null;

      try {
        //检查是否为Multipart请求,如果是则返回的是一个MultipartHttpServletRequest类型的request,不是则返回原来的request
         processedRequest = checkMultipart(request);
        //根据返回是否原来的对象来判断,request是否已经被处理过
         multipartRequestParsed = (processedRequest != request);

         //根据uri找到HandlerExecutionChain(包含了我们写的处理器和拦截器)
         mappedHandler = getHandler(processedRequest);
         if (mappedHandler == null || mappedHandler.getHandler() == null) {
            noHandlerFound(processedRequest, response);
            return;
         }

         //获取到处理器适配器,用于执行HandlerExecutionChain
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

         //处理last-modified缓存机制,处理器支持需要实现LastModified接口
         String method = request.getMethod();
         boolean isGet = "GET".equals(method);
         //last-modified 只支持get或者HEAD请求
         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);
            }
           //修改时间与上次请求的时间一致,那么表示资源未改变,直接返回304状态码,浏览器使用上次缓存结果
            if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
               return;
            }
         }
			//执行mappedHandler中所有HandlerInterceptor(拦截器)applyPreHandle方法
         if (!mappedHandler.applyPreHandle(processedRequest, response)) {
           //如果有applyPreHandle返回的是false,则结束doDispatch方法的执行
            return;
         }

         // 执行处理器方法,返回ModelAndView
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
		//如果本次是异步请求,直接退出doDispatch方法的执行
         if (asyncManager.isConcurrentHandlingStarted()) {
            return;
         }
		//如果返回的ModelAndView中的ViewName为空时,设置一个默认的ViewName
         applyDefaultViewName(processedRequest, mv);
        //执行mappedHandler中所有HandlerInterceptor(拦截器)applyPostHandle方法
         mappedHandler.applyPostHandle(processedRequest, response, mv);
      }
      catch (Exception ex) {
        //保存异常,用于后面的@ExceptionHandler方法处理
         dispatchException = ex;
      }
      catch (Throwable err) {
         // As of 4.3, we're processing Errors thrown from handler methods as well,
         // making them available for @ExceptionHandler methods and other scenarios.
         //保存错误,用于后面的@ExceptionHandler方法处理
         dispatchException = new NestedServletException("Handler dispatch failed", err);
      }
     //处理结果并响应浏览器
      processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
   }
  
   catch (Exception ex) {
     //异常时,也会执行mappedHandler中所有HandlerInterceptor(拦截器)AfterCompletion方法
      triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
   }
   catch (Throwable err) {
     //错误时,也会执行mappedHandler中所有HandlerInterceptor(拦截器)AfterCompletion方法
      triggerAfterCompletion(processedRequest, response, mappedHandler,
            new NestedServletException("Handler processing failed", err));
   }
   finally {
      if (asyncManager.isConcurrentHandlingStarted()) {
         //如果是异步请求,执行mappedHandler中所有AsyncHandlerInterceptor(异步拦截器)的afterConcurrentHandlingStarted方法
         if (mappedHandler != null) {
            mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
         }
      }
      else {
         // 关闭Multipart请求的相关资源
         if (multipartRequestParsed) {
            cleanupMultipart(processedRequest);
         }
      }
   }
}

Next, a detailed analysis of several important steps:

[TOC]

 

1) getHandler (processedRequest): Locate the processor execution chain needs to perform (HandlerExecutionChain)
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  //遍历每一个HandlerMapping执行getHandler方法,直到获取到一个HandlerExecutionChain,并返回
   for (HandlerMapping hm : this.handlerMappings) {
      if (logger.isTraceEnabled()) {
         logger.trace(
               "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
      }
      HandlerExecutionChain handler = hm.getHandler(request);
      if (handler != null) {
         return handler;
      }
   }
   return null;
}

DispatcherServlet.properties default configuration HandlerMapping:

org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping: (alias) The Controller name or alias lookup in a container ioc

org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping (obsolete)

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter (instead of DefaultAnnotationHandlerMapping: look for marked @RequestMapping and other annotation processor, the most commonly used

 

2) getHandlerAdapter (mappedHandler.getHandler ()) corresponding to find support processor adapter processor are now generally used RequestMappingHandlerAdapter:
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
  //遍历所有的HandlerAdapter,执行supports来找到支持的对应处理器的处理器适配器
   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");
}

DispatcherServlet.properties default configuration HandlerAdapter:

org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter: to achieve the implementation of the Controller RequestHandler interface

org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter: to achieve the implementation of the Controller Controller Interface

org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter(已过时)

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping (instead of AnnotationMethodHandlerAdapter): marked performed @RequestMapping like annotation processor, the most common

 

3) mappedHandler.applyPreHandle (processedRequest, response) performs all HandlerExecutionChain interceptor applyPreHandle (processedRequest, response) method
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
  	//遍历执行Interceptor.preHandle
   HandlerInterceptor[] interceptors = getInterceptors();
   if (!ObjectUtils.isEmpty(interceptors)) {
      for (int i = 0; i < interceptors.length; i++) {
         HandlerInterceptor interceptor = interceptors[i];
        //preHandle(request, response, this.handler)返回false,则triggerAfterCompletion(request, response, null),并不再执行接下来的其他处理器的preHandle
         if (!interceptor.preHandle(request, response, this.handler)) {
            triggerAfterCompletion(request, response, null);
            return false;
         }
        //保存最后一个preHandle(request, response, this.handler)返回true的拦截器索引值
         this.interceptorIndex = i;
      }
   }
   return true;
}
4) triggerAfterCompletion (request, response, null): applyPreHandle method if there are interceptors return false, afterCompletion execution method interceptor is triggered:
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
      throws Exception {
   HandlerInterceptor[] interceptors = getInterceptors();
   if (!ObjectUtils.isEmpty(interceptors)) {
     //逆序执行上一步preHandle(request, response, this.handler)返回true的拦截器的afterCompletion方法
      for (int i = this.interceptorIndex; i >= 0; i--) {
         HandlerInterceptor interceptor = interceptors[i];
         try {
            interceptor.afterCompletion(request, response, this.handler, ex);
         }
         catch (Throwable ex2) {
            logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
         }
      }
   }
}

 

5) ha.handle (processedRequest, response, mappedHandler.getHandler ()) executed by a processor using the processor adapter Method:
@Override//handlerMethod保存了处理器对象和当前需要执行的处理器方法等信息
protected ModelAndView handleInternal(HttpServletRequest request,
      HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

   ModelAndView mav;
   checkRequest(request);

   // this.synchronizeOnSession 默认为false,对于同一个session的request,是否同步执行处理器方法.
   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 {
      //执行处理器方法
      mav = invokeHandlerMethod(request, response, handlerMethod);
   }

   if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
      if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
         applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
      }
      else {
         prepareResponse(response);
      }
   }

   return mav;
}

Look directly invokeHandlerMethod (request, response, handler):

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

		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
          	//查找处理器中标注了@InitBinder的方法及相应的@ControllerAdvice类,保存在binderFactory
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
          	//查找处理器中标注了@ModelAttribute的方法及相应的@ControllerAdvice类,保存在modelFactory中
			ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
			//ServletInvocableHandlerMethod:可执行的处理器方法
			ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
          	//设置处理器方法参数解析器
			invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
          	//处理器方法返回值的处理器
			invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
			invocableMethod.setDataBinderFactory(binderFactory);
          	//参数名称发现器
			invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
			//mavContainer用于存放所有可能会用到的ModelAndView
			ModelAndViewContainer mavContainer = new ModelAndViewContainer();
          	//添加重定向参数
			mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
          	//初始化model,就是填充model,添加Sesson中的参数名与处理器方法参数一致的参数,执行@ModelAttribute标注的处理器方法
			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);
          	//注册返回值为Callable的异步拦截器
			asyncManager.registerCallableInterceptors(this.callableInterceptors);
          	//注册返回值为DeferredResult的异步拦截器
			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;
			}
			//返回ModelAndView对象
			return getModelAndView(mavContainer, modelFactory, webRequest);
		}
		finally {
			webRequest.requestCompleted();
		}
	}

 

6) mappedHandler.applyPostHandle (processedRequest, response, mv): postHandle method performed interceptor
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);
		}
	}
}

 

7) processDispatchResult (processedRequest, response, mappedHandler, mv, dispatchException): and in response to the processing result to the browser
//exception 执行处理器方法报错时被捕获的异常
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);
        //处理异常,执行自定义异常处理方法即被@ExceptionHandler标注,并返回一个ModelAndView
         mv = processHandlerException(request, response, handler, exception);
         errorView = (mv != null);
      }
   }

   //如果mv不为空,且没有被清理,也就是请求在此之前还没有响应浏览器
   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) {
      //执行所有拦截器的AfterCompletion方法
      mappedHandler.triggerAfterCompletion(request, response, null);
   }
}

End. . .

Guess you like

Origin www.cnblogs.com/qzlcl/p/11204372.html