> 文档中心 > SpringMVC之请求处理流程

SpringMVC之请求处理流程

SpringMVC之请求处理流程

我们知道DispatcherServlet就是一个HttpServlet,而HttpServlet的请求就从doGet/doPost开始

DispatcherServlet本身没有实现doGet/doPost,而由他的父类FrameworkServlet实现,源码如下

FrameworkServlet.doGet/doPost

@Overrideprotected final void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {processRequest(request, response);}/*** Delegate POST requests to {@link #processRequest}.* @see #doService*/@Overrideprotected final void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {processRequest(request, response);}

processRequest

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {    long startTime = System.currentTimeMillis();    Throwable failureCause = null; //previousLocaleContext获取和当前线程相关的LocaleContext,根据已有请求构造一个新的和当前线程相关的LocaleContext    LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();    LocaleContext localeContext = buildLocaleContext(request);    //previousAttributes获取和当前线程绑定的RequestAttributes    RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes(); //为已有请求构造新的ServletRequestAttributes,加入预绑定属性    ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);//异步请求处理    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);    asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());    //initContextHolders让新构造的RequestAttributes和ServletRequestAttributes和当前线程绑定,加入到ThreadLocal,完成绑定    initContextHolders(request, localeContext, requestAttributes);    try { //抽象方法doService由FrameworkServlet子类DispatcherServlet重写 doService(request, response);    }catch (ServletException | IOException ex) { failureCause = ex; throw ex;    }catch (Throwable ex) { failureCause = ex; throw new NestedServletException("Request processing failed", ex);    }finally { //解除RequestAttributes,ServletRequestAttributes和当前线程的绑定 resetContextHolders(request, previousLocaleContext, previousAttributes); if (requestAttributes != null) {     requestAttributes.requestCompleted(); } logResult(request, response, failureCause, asyncManager); //注册监听事件ServletRequestHandledEvent,在调用上下文的时候产生Event publishRequestHandledEvent(request, response, startTime, failureCause);    }}

doService

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {    logRequest(request);    // Keep a snapshot of the request attributes in case of an include,    // to be able to restore the original attributes after the include.    Map attributesSnapshot = null;    if (WebUtils.isIncludeRequest(request)) { attributesSnapshot = new HashMap();//保存request域中的数据,存一份快照 Enumeration attrNames = request.getAttributeNames(); while (attrNames.hasMoreElements()) {     String attrName = (String) attrNames.nextElement();     if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {  attributesSnapshot.put(attrName, request.getAttribute(attrName));     } }    }    //设置web应用上下文    request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());    //国际化本地    request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);    //样式    request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);    //设置样式资源    request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());    //请求刷新时保存属性    if (this.flashMapManager != null) { FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response); if (inputFlashMap != null) {     request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap)); } //Flash attributes 在对请求的重定向生效之前被临时存储(通常是在session)中,并且在重定向之后被立即移除 request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); //FlashMap 被用来管理 flash attributes 而 FlashMapManager 则被用来存储,获取和管理 FlashMap 实体 request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);    }    try {    //核心方法 doDispatch(request, response);    }finally { if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {     // Restore the original attribute snapshot, in case of an include.     if (attributesSnapshot != null) {  restoreAttributesAfterInclude(request, attributesSnapshot);//将快照覆盖回去     } }    }}

DispatcherServlet.doDispatch

这个方法就是处理请求的核心方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {    HttpServletRequest processedRequest = request;    HandlerExecutionChain mappedHandler = null;    boolean multipartRequestParsed = false;//异步处理,webflux相关    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);    try { ModelAndView mv = null; Exception dispatchException = null; try {     //将request转换成multipartRequest,并检查是否解析成功(判断是否有文件上传)     processedRequest = checkMultipart(request);     multipartRequestParsed = (processedRequest != request);     //根据请求信息获取handler(包含了拦截器),组成HandlerExecutionChain     mappedHandler = getHandler(processedRequest);     if (mappedHandler == null) {  noHandlerFound(processedRequest, response);  return;     }     //根据handler获取adapter---命名为ha     HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());     // Process last-modified header, if supported by the handler.     String method = request.getMethod();     boolean isGet = "GET".equals(method);     if (isGet || "HEAD".equals(method)) {  long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {      return;  }     }//执行拦截器逻辑     if (!mappedHandler.applyPreHandle(processedRequest, response)) {  return;     }     //执行业务处理,返回视图模型     mv = ha.handle(processedRequest, response, mappedHandler.getHandler());     if (asyncManager.isConcurrentHandlingStarted()) {  return;     }//给视图模型设置viewName     applyDefaultViewName(processedRequest, mv);     //拦截器逻辑     mappedHandler.applyPostHandle(processedRequest, response, mv); }catch (Exception ex) {     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.     dispatchException = new NestedServletException("Handler dispatch failed", err); } //处理请求结果,使用了组件LocaleResolver, ViewResolver和ThemeResolver(view#render) processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);    }catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex);    }catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler,   new NestedServletException("Handler processing failed", err));    }finally { if (asyncManager.isConcurrentHandlingStarted()) {     // Instead of postHandle and afterCompletion     if (mappedHandler != null) {  mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);     } }else {     // Clean up any resources used by a multipart request.     if (multipartRequestParsed) {  cleanupMultipart(processedRequest);     } }    }}

DispatcherServlet.getHandler

@Nullableprotected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {   if (this.handlerMappings != null) {      for (HandlerMapping mapping : this.handlerMappings) {  HandlerExecutionChain handler = mapping.getHandler(request);  if (handler != null) {     return handler;  }      }   }   return null;}

这里的this.handlerMappings就是9大组件之一,在web容器启动时方法中初始化.

过滤器和拦截器

  • 过滤器拦截DispatcherServlet,属于web服务器层面
  • 拦截器可以拦截到具体方法,属于springmvc框架

HandlerExecutionChain对象包含处理器+拦截器链

public class HandlerExecutionChain {   private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);//真正的处理器   private final Object handler;//配置在springmvc配置文件的拦截器   @Nullable   private HandlerInterceptor[] interceptors;//所有拦截器   @Nullable   private List interceptorList;}

AbstractHandlerMapping.getHandler

/** * 返回请求处理的HandlerExecutionChain,从AbstractHandlerMapping中的adaptedInterceptors和mappedInterceptors属性中获取 */@Override@Nullablepublic final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {    // getHandlerInternal()为抽象方法,具体需子类实现    Object handler = getHandlerInternal(request);    if (handler == null) { handler = getDefaultHandler();    }    if (handler == null) { return null;    }    // Bean name or resolved handler?    if (handler instanceof String) { String handlerName = (String) handler; handler = obtainApplicationContext().getBean(handlerName);    } // 将请求处理器封装为HandlerExectionChain    HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); // 对跨域的处理    if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config);    }    return executionChain;}

AbstractHandlerMapping.getHandlerExecutionChain

/** * 构建handler处理器的HandlerExecutionChain,包括拦截器 */protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {//将handler处理成HandlerExecutionChain    HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?     (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);    // 迭代添加拦截器,private final List adaptedInterceptors = new ArrayList();    for (HandlerInterceptor interceptor : this.adaptedInterceptors) { // 如果拦截器是MappedInterceptor,判断是否对该handler进行拦截,是的情况下添加 if (interceptor instanceof MappedInterceptor) {     MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;     if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {  chain.addInterceptor(mappedInterceptor.getInterceptor());     } } else {  // HandlerInterceptor直接添加,即通过HandingMapping属性配置的拦截器     chain.addInterceptor(interceptor); }    }    return chain;}// new HandlerExecutionChain(handler),将handler变成HandlerExecutionChainpublic HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... interceptors) {if (handler instanceof HandlerExecutionChain) {HandlerExecutionChain originalChain = (HandlerExecutionChain) handler;this.handler = originalChain.getHandler();//new一个interceptorListthis.interceptorList = new ArrayList();//将HandlerInterceptor合并到interceptorListCollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);}else {this.handler = handler;this.interceptors = interceptors;}}

总结一下

就是把处理器+拦截器链组合成 HandlerExecutionChain 对象,看一下最普通的返回值

DispatcherServlet.getHandlerAdapter

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {   if (this.handlerAdapters != null) {      for (HandlerAdapter adapter : this.handlerAdapters) {      //判断adapter是否适配handler,适配的话就返回,一般情况下handler是HandlerMethod类型  if (adapter.supports(handler)) {     //这里一般返回RequestMappingHandlerAdapter     return adapter;  }      }   }   throw new ServletException("No adapter for handler [" + handler +  "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");  }//this.handlerAdaptersprivate List handlerAdapters;//RequestMappingHandlerAdapter的父类AbstractHandlerMethodAdapter的代码实现@Overridepublic final boolean supports(Object handler) {return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));}

HandlerAdapter就是适配器对象

RequestMappingHandlerAdapter

RequestMappingHandlerAdapter就是处理@RequestMapping注解的适配器

/** * Extension of {@link AbstractHandlerMethodAdapter} that supports * {@link RequestMapping @RequestMapping} annotated {@link HandlerMethod HandlerMethods}. * * 

Support for custom argument and return value types can be added via * {@link #setCustomArgumentResolvers} and {@link #setCustomReturnValueHandlers}, * or alternatively, to re-configure all argument and return value types, * use {@link #setArgumentResolvers} and {@link #setReturnValueHandlers}. * * @author Rossen Stoyanchev * @author Juergen Hoeller * @since 3.1 * @see HandlerMethodArgumentResolver * @see HandlerMethodReturnValueHandler */public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean { ... }

HandlerExecutionChain.applyPreHandle

执行拦截器逻辑

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)) {  //拦截后的方法afterCompletion     triggerAfterCompletion(request, response, null);     return false;  }  this.interceptorIndex = i;      }   }   return true;}

HandlerAdapter.handle

使用适配器执行业务处理,返回视图模型

@Override@Nullablepublic final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception {   return handleInternal(request, response, (HandlerMethod) handler);}

RequestMappingHandlerAdapter.handleInternal

@Overrideprotected 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 {   //核心方法      // No synchronization on session demanded at all...      mav = invokeHandlerMethod(request, response, handlerMethod);   }   if (!response.containsHeader(HEADER_CACHE_CONTROL)) {      if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {  applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);      }      else {  prepareResponse(response);      }   }   return mav;}

RequestMappingHandlerAdapter.invokeHandlerMethod

@Nullableprotected ModelAndView invokeHandlerMethod(HttpServletRequest request,      HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {   ServletWebRequest webRequest = new ServletWebRequest(request, response);   try {      WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);      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));      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);      } //核心方法      invocableMethod.invokeAndHandle(webRequest, mavContainer);      if (asyncManager.isConcurrentHandlingStarted()) {  return null;      }      return getModelAndView(mavContainer, modelFactory, webRequest);   }   finally {      webRequest.requestCompleted();   }}

invocableMethod.invokeAndHandle

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,      Object... providedArgs) throws Exception {   //这里就在处理方法,得到返回值   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 {      this.returnValueHandlers.handleReturnValue(     returnValue, getReturnValueType(returnValue), mavContainer, webRequest);   }   catch (Exception ex) {      if (logger.isTraceEnabled()) {  logger.trace(formatErrorForReturnValue(returnValue), ex);      }      throw ex;   }}

invokeForRequest();

这个方法就是在处理@RequestMapper注解的方法,并通过反射得到返回值

@Nullablepublic Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,      Object... providedArgs) throws Exception {//获取方法参数   Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);   if (logger.isTraceEnabled()) {      logger.trace("Arguments: " + Arrays.toString(args));   }   //利用反射执行方法,得到返回值   return doInvoke(args);}

doInvoke(Object... args)

@Nullableprotected Object doInvoke(Object... args) throws Exception {   ReflectionUtils.makeAccessible(getBridgedMethod());   try {     //这里getBridgedMethod()就是Method,得到Method然后反射执行方法,得到返回值      return getBridgedMethod().invoke(getBean(), args);   }   catch (IllegalArgumentException ex) {      assertTargetBean(getBridgedMethod(), getBean(), args);      String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");      throw new IllegalStateException(formatInvokeError(text, args), ex);   }   catch (InvocationTargetException ex) {      // Unwrap for HandlerExceptionResolvers ...      Throwable targetException = ex.getTargetException();      if (targetException instanceof RuntimeException) {  throw (RuntimeException) targetException;      }      else if (targetException instanceof Error) {  throw (Error) targetException;      }      else if (targetException instanceof Exception) {  throw (Exception) targetException;      }      else {  throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);      }   }}

这里得到返回值后,springmvc会进行一系列处理,最后用IO write出去

HandlerExecutionChain.applyPostHandle

执行拦截器中postHandle方法

void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable 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);      }   }}

processDispatchResult

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,      @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,      @Nullable Exception exception) throws Exception {   boolean errorView = false;//异常处理   if (exception != null) {   //ModelAndViewDefiningException类型,会携带对应的ModelAndView      if (exception instanceof ModelAndViewDefiningException) {  logger.debug("ModelAndViewDefiningException encountered", exception);  mv = ((ModelAndViewDefiningException) exception).getModelAndView();      }      else {      //由对应的处理器handler进行异常处理,返回ModelAndView。其中使用了HandlerExceptionResolver。  Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  mv = processHandlerException(request, response, handler, exception);  errorView = (mv != null);      }   }   // Did the handler return a view to render?   if (mv != null && !mv.wasCleared()) {      render(mv, request, response);      if (errorView) {  WebUtils.clearErrorRequestAttributes(request);      }   }   else {      if (logger.isTraceEnabled()) {  logger.trace("No view rendering, null ModelAndView returned.");      }   }   if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {      // Concurrent handling started during a forward      return;   }   if (mappedHandler != null) {      //这里执行拦截器的afterCompletion方法      // Exception (if any) is already handled..      mappedHandler.triggerAfterCompletion(request, response, null);   }}

mappedHandler.triggerAfterCompletion

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)      throws Exception {   HandlerInterceptor[] interceptors = getInterceptors();   if (!ObjectUtils.isEmpty(interceptors)) {      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);  }      }   }}

HandlerMapping

public interface HandlerMapping {    // 返回请求的一个处理程序handler和拦截器interceptors    @Nullable    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;}

HandlerMapping作用是将请求映射到处理程序,以及预处理和处理后的拦截器列表,映射是基于一些标准的,其中的细节因不同的实现而不相同。这是官方文档上一段描述,该接口只有一个方法getHandler(request),返回一个HandlerExecutionChain对象

如果配置了这个标签,Spring MVC会默认添加RequestMappingHandlerMapping和RequestMappingHandlerAdapter


Spring MVC会加载在当前系统中所有实现了HandlerMapping接口的bean,再进行按优先级排序。

  • SimpleUrlHandlerMapping 支持映射bean实例和映射bean名称,需要手工维护urlmap,通过key指定访问路径,

  • BeanNameUrlHandlerMapping 支持映射bean的name属性值,扫描以”/“开头的beanname,通过id指定访问路径

  • RequestMappingHandlerMapping 支持@Controller和@RequestMapping注解,通过注解定义访问路径

AbstractHandlerMapping

模板类

protected void initApplicationContext() throws BeansException {    // 提供给子类去重写的,不过Spring并未去实现,提供扩展    extendInterceptors(this.interceptors);    // 加载拦截器    detectMappedInterceptors(this.adaptedInterceptors);    // 归并拦截器    initInterceptors();}/** * 空实现 */protected void extendInterceptors(List interceptors) {}/** * 从上下文中加载MappedInterceptor类型的拦截器,比如我们在配置文件中使用 *  * 标签配置的拦截器 */protected void detectMappedInterceptors(List mappedInterceptors) {    mappedInterceptors.addAll(     BeanFactoryUtils.beansOfTypeIncludingAncestors(      obtainApplicationContext(), MappedInterceptor.class, true, false).values());}/** * 合并拦截器,即将中的拦截器与HandlerMapping中通过属性interceptors设置的拦截器进行合并 */protected void initInterceptors() {    if (!this.interceptors.isEmpty()) { for (int i = 0; i < this.interceptors.size(); i++) {     Object interceptor = this.interceptors.get(i);     if (interceptor == null) {  throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");     }     // 适配后加入adaptedInterceptors     this.adaptedInterceptors.add(adaptInterceptor(interceptor)); }    }}/** * 适配HandlerInterceptor和WebRequestInterceptor */protected HandlerInterceptor adaptInterceptor(Object interceptor) {    if (interceptor instanceof HandlerInterceptor) { return (HandlerInterceptor) interceptor;    } else if (interceptor instanceof WebRequestInterceptor) { return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);    } else { throw new IllegalArgumentException("Interceptor type not supported: " +    interceptor.getClass().getName());    }}/** * 返回请求处理的HandlerExecutionChain,从AbstractHandlerMapping中的adaptedInterceptors和mappedInterceptors属性中获取 */@Override@Nullablepublic final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {    // getHandlerInternal()为抽象方法,具体需子类实现    Object handler = getHandlerInternal(request);    if (handler == null) { handler = getDefaultHandler();    }    if (handler == null) { return null;    }    // Bean name or resolved handler?    if (handler instanceof String) { String handlerName = (String) handler; handler = obtainApplicationContext().getBean(handlerName);    } // 将请求处理器封装为HandlerExectionChain    HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);    // 对跨域的处理    if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config);    }    return executionChain;}/** * 钩子函数,需子类实现 */@Nullableprotected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;/** * 构建handler处理器的HandlerExecutionChain,包括拦截器 */protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {    HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?     (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);    // 迭代添加拦截器    for (HandlerInterceptor interceptor : this.adaptedInterceptors) { // 如果拦截器是MappedInterceptor,判断是否对该handler进行拦截,是的情况下添加 if (interceptor instanceof MappedInterceptor) {     MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;     if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {  chain.addInterceptor(mappedInterceptor.getInterceptor());     } } else { // HandlerInterceptor直接添加,即通过HandingMapping属性配置的拦截器     chain.addInterceptor(interceptor); }    }    return chain;}

RequestMappingHandlerMapping

处理注解@RequestMapping及@Controller

  • 实现InitializingBean接口,增加了bean初始化的能力,也就是说在bean初始化时可以做一些控制
  • 实现EmbeddedValueResolverAware接口,即增加了读取属性文件的能力

继承自AbstractHandlerMethodMapping

//RequestMappingHandlerMapping@Overridepublic void afterPropertiesSet() {    this.config = new RequestMappingInfo.BuilderConfiguration();    this.config.setUrlPathHelper(getUrlPathHelper());    this.config.setPathMatcher(getPathMatcher());    this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);    this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);    this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch);    this.config.setContentNegotiationManager(getContentNegotiationManager());    super.afterPropertiesSet();}//AbstractHandlerMethodMapping@Overridepublic void afterPropertiesSet() {    initHandlerMethods();}protected void initHandlerMethods() {    //获取上下文中所有bean的name,不包含父容器    for (String beanName : getCandidateBeanNames()) { if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {     processCandidateBean(beanName); }    }    //日志记录HandlerMethods的总数量    handlerMethodsInitialized(getHandlerMethods());}protected void processCandidateBean(String beanName) {    Class beanType = null;    try { //根据name找出bean的类型 beanType = obtainApplicationContext().getType(beanName);    } catch (Throwable ex) { if (logger.isTraceEnabled()) {     logger.trace("Could not resolve type for bean '" + beanName + "'", ex); }    }    //处理Controller和RequestMapping    if (beanType != null && isHandler(beanType)) { detectHandlerMethods(beanName);    }}//RequestMappingHandlerMapping@Overrideprotected boolean isHandler(Class beanType) {    //获取@Controller和@RequestMapping    return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||     AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));}//整个controller类的解析过程 protected void detectHandlerMethods(Object handler) {    //根据name找出bean的类型Class handlerType = (handler instanceof String ?obtainApplicationContext().getType((String) handler) : handler.getClass());if (handlerType != null) { //获取真实的controller,如果是代理类获取父类Class userType = ClassUtils.getUserClass(handlerType); //对真实的controller所有的方法进行解析和处理  key为方法对象,T为注解封装后的对象RequestMappingInfoMap methods = MethodIntrospector.selectMethods(userType,(MethodIntrospector.MetadataLookup) method -> {try { // 调用子类RequestMappingHandlerMapping的getMappingForMethod方法进行处理,即根据RequestMapping注解信息创建匹配条件RequestMappingInfo对象return getMappingForMethod(method, userType);}catch (Throwable ex) {throw new IllegalStateException("Invalid mapping on handler class [" +userType.getName() + "]: " + method, ex);}});if (logger.isTraceEnabled()) {logger.trace(formatMappings(userType, methods));}methods.forEach((method, mapping) -> {  //找出controller中可外部调用的方法Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);  //注册处理方法registerHandlerMethod(handler, invocableMethod, mapping);});}}//requestMapping封装成RequestMappingInfo对象protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) {    RequestMappingInfo info = createRequestMappingInfo(method);//解析方法上的requestMapping    if (info != null) { //解析方法所在类上的requestMapping RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) {     info = typeInfo.combine(info);//合并类和方法上的路径,比如Controller类上有@RequestMapping("/demo"),方法的@RequestMapping("/demo1"),结果为"/demo/demo1" } String prefix = getPathPrefix(handlerType);//合并前缀 if (prefix != null) {     info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info); }    }    return info;}private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {    //找到方法上的RequestMapping注解    RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element,    RequestMapping.class);    //获取自定义的类型条件(自定义的RequestMapping注解)    RequestCondition condition = (element instanceof Class ?  getCustomTypeCondition((Class) element) :      getCustomMethodCondition((Method) element));    return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);}protected RequestMappingInfo createRequestMappingInfo(    RequestMapping requestMapping, @Nullable RequestCondition customCondition) {    //获取RequestMapping注解的属性,封装成RequestMappingInfo对象    RequestMappingInfo.Builder builder = RequestMappingInfo .paths(resolveEmbeddedValuesInPatterns(requestMapping.path())) .methods(requestMapping.method()) .params(requestMapping.params()) .headers(requestMapping.headers()) .consumes(requestMapping.consumes()) .produces(requestMapping.produces()) .mappingName(requestMapping.name());    if (customCondition != null) { builder.customCondition(customCondition);    }    return builder.options(this.config).build();}//再次封装成对应的对象    面向对象编程  每一个属性都存在多个值得情况需要排重封装@Overridepublic RequestMappingInfo build() {    ContentNegotiationManager manager = this.options.getContentNegotiationManager();    PatternsRequestCondition patternsCondition = new PatternsRequestCondition( this.paths, this.options.getUrlPathHelper(), this.options.getPathMatcher(), this.options.useSuffixPatternMatch(), this.options.useTrailingSlashMatch(), this.options.getFileExtensions());    return new RequestMappingInfo(this.mappingName, patternsCondition,      new RequestMethodsRequestCondition(this.methods),      new ParamsRequestCondition(this.params),      new HeadersRequestCondition(this.headers),      new ConsumesRequestCondition(this.consumes, this.headers),      new ProducesRequestCondition(this.produces, this.headers, manager),      this.customCondition);}

registerHandlerMethod

protected void registerHandlerMethod(Object handler, Method method, T mapping) {   this.mappingRegistry.register(mapping, handler, method);}//mapping是RequestMappingInfo对象   handler是controller类的beanName   method为接口方法public void register(T mapping, Object handler, Method method) {    ...    this.readWriteLock.writeLock().lock();    try { //beanName和method封装成HandlerMethod对象 HandlerMethod handlerMethod = createHandlerMethod(handler, method); //验证RequestMappingInfo是否有对应不同的method,有则抛出异常 validateMethodMapping(handlerMethod, mapping); //RequestMappingInfo和handlerMethod绑定 this.mappingLookup.put(mapping, handlerMethod); List directUrls = getDirectUrls(mapping);//可以配置多个url for (String url : directUrls) {     //url和RequestMappingInfo绑定   可以根据url找到RequestMappingInfo,再找到handlerMethod     this.urlLookup.add(url, mapping); } String name = null; if (getNamingStrategy() != null) {     name = getNamingStrategy().getName(handlerMethod, mapping);     addMappingName(name, handlerMethod);//方法名和Method绑定 } CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping); if (corsConfig != null) {     this.corsLookup.put(handlerMethod, corsConfig); }//将RequestMappingInfo  url  handlerMethod绑定到MappingRegistration对象  放入map this.registry.put(mapping, new MappingRegistration(mapping, handlerMethod, directUrls, name));    }    finally { this.readWriteLock.writeLock().unlock();    }}

HandlerAdapters

Spring MVC为我们提供了多种处理用户的处理器(Handler),Spring实现的处理器类型有Servlet、Controller、HttpRequestHandler以及注解类型的处理器,即我们可以通过实现这些接口或者注解我们的类来使用这些处理器,那么针对不同类型的处理器,如何将用户请求转发到相应类型的处理器方法中的呢,这就需求Spring MVC的处理器适配器来完成适配操作,这就是处理器适配器要完成的工作。

  • SimpleServletHandlerAdapter 适配Servlet处理器

  • HttpRerquestHandlerAdapter 适配HttpRequestHandler处理器

  • RequestMappingHandlerAdapter 适配注解处理器

  • SimpleControllerHandlerAdapter 适配Controller处理器

Spring MVC默认使用的处理器适配器为:HttpRequestHandlerAdapter、SimpleServletHandlerAdapter、RequestMappingHandlerAdapter三种。

RequestMappingHandlerAdapter

通过继承抽象类AbstractHandlerMethodAdapter实现了HandlerAdapter接口

请求适配给 @RequestMapping 类型的Handler处理。

采用反射机制调用url请求对应的Controller中的方法(这其中还包括参数处理),返回执行结果值,完成HandlerAdapter的使命

getLastModified直接返回-1

@Overrideprotected long getLastModifiedInternal(HttpServletRequest request, HandlerMethod handlerMethod) {    return -1;}//通过父类调用@Overrideprotected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {     ModelAndView mav;    checkRequest(request);     // 判断当前是否需要支持在同一个session中只能线性地处理请求    if (this.synchronizeOnSession) { // 获取当前请求的session对象 HttpSession session = request.getSession(false); if (session != null) {     // 为当前session生成一个唯一的可以用于锁定的key     Object mutex = WebUtils.getSessionMutex(session);     synchronized (mutex) {  // 对HandlerMethod进行参数等的适配处理,并调用目标handler  mav = invokeHandlerMethod(request, response, handlerMethod);     } } else {     // 如果当前不存在session,则直接对HandlerMethod进行适配     mav = invokeHandlerMethod(request, response, handlerMethod); }    } else { // 如果当前不需要对session进行同步处理,则直接对HandlerMethod进行适配 mav = invokeHandlerMethod(request, response, handlerMethod);    }     // 判断当前请求头中是否包含Cache-Control请求头,如果不包含,则对当前response进行处理,为其设置过期时间    if (!response.containsHeader(HEADER_CACHE_CONTROL)) { // 如果当前SessionAttribute中存在配置的attributes,则为其设置过期时间。 // 这里SessionAttribute主要是通过@SessionAttribute注解生成的 if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {     applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else {     // 如果当前不存在SessionAttributes,则判断当前是否存在Cache-Control设置,     // 如果存在,则按照该设置进行response处理,如果不存在,则设置response中的     // Cache的过期时间为-1,即立即失效     prepareResponse(response); }    }    return mav;}//核心处理流程@Nullableprotected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {     ServletWebRequest webRequest = new ServletWebRequest(request, response);    try { // 获取容器中全局配置的InitBinder和当前HandlerMethod所对应的Controller中配置的InitBinder,用于进行参数的绑定 WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);  // 获取容器中全局配置的ModelAttribute和当前HandlerMethod所对应的Controller // 中配置的ModelAttribute,这些配置的方法将会在目标方法调用之前进行调用 ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);  // 将handlerMethod封装为一个ServletInvocableHandlerMethod对象,该对象用于对当前request的整体调用流程进行了封装 ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);  if (this.argumentResolvers != null) {     // 设置当前容器中配置的所有ArgumentResolver     invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); }  if (this.returnValueHandlers != null) {     // 设置当前容器中配置的所有ReturnValueHandler     invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); }  // 将前面创建的WebDataBinderFactory设置到ServletInvocableHandlerMethod中 invocableMethod.setDataBinderFactory(binderFactory);  // 设置ParameterNameDiscoverer,该对象将按照一定的规则获取当前参数的名称 invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);  ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));  // 这里initModel()方法主要作用是调用前面获取到的@ModelAttribute标注的方法, // 从而达到@ModelAttribute标注的方法能够在目标Handler调用之前调用的目的 modelFactory.initModel(webRequest, mavContainer, invocableMethod); mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);  // 获取当前的AsyncWebRequest,这里AsyncWebRequest的主要作用是用于判断目标 // handler的返回值是否为WebAsyncTask或DefferredResult,如果是这两种中的一种, // 则说明当前请求的处理应该是异步的。所谓的异步,指的是当前请求会将Controller中 // 封装的业务逻辑放到一个线程池中进行调用,待该调用有返回结果之后再返回到response中。 // 这种处理的优点在于用于请求分发的线程能够解放出来,从而处理更多的请求,只有待目标任务 // 完成之后才会回来将该异步任务的结果返回。 AsyncWebRequest asyncWebRequest = WebAsyncUtils     .createAsyncWebRequest(request, response); asyncWebRequest.setTimeout(this.asyncRequestTimeout);  // 封装异步任务的线程池,request和interceptors到WebAsyncManager中 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();     if (logger.isDebugEnabled()) {  logger.debug("Found concurrent result value [" + result + "]");     }   // 封装异步任务的处理结果,虽然封装的是一个HandlerMethod,但只是Spring简单的封装     // 的一个Callable对象,该对象中直接将调用结果返回了。这样封装的目的在于能够统一的     // 进行右面的ServletInvocableHandlerMethod.invokeAndHandle()方法的调用     invocableMethod = invocableMethod.wrapConcurrentResult(result); }  // 对请求参数进行处理,调用目标HandlerMethod,并且将返回值封装为一个ModelAndView对象 invocableMethod.invokeAndHandle(webRequest, mavContainer); if (asyncManager.isConcurrentHandlingStarted()) {     return null; }  // 对封装的ModelAndView进行处理,主要是判断当前请求是否进行了重定向,如果进行了重定向, // 还会判断是否需要将FlashAttributes封装到新的请求中 return getModelAndView(mavContainer, modelFactory, webRequest);    } finally { // 调用request destruction callbacks和对SessionAttributes进行处理 webRequest.requestCompleted();    }}
  • 获取当前容器中使用 @InitBinder 注解注册的属性转换器;
  • 获取当前容器中使用 @ModelAttribute 标注但没有使用 @RequestMapping 标注的方法,并且在调用目标方法之前调用这些方法;
  • 判断目标handler返回值是否使用了WebAsyncTask或DefferredResult封装,如果封装了,则按照异步任务的方式进行执行;
  • 处理请求参数,调用目标方法和处理返回值。

总结一下

  • 所有请求都会经过DispatcherServlet.doDispatch处理
  • 将请求的内容和拦截器链处理成HandlerExecutionChain,一般情况下handler是HandlerMethod类型的,
  • 寻找处理器对应的合适的适配器,一般情况下就是RequestMappingHandlerAdapter,用于处理@RequestMapping注解的适配器
  • 执行拦截器链的preHandle方法
  • 使用找到的适配器利用反射去执行方法,获取返回值,并响应
  • 执行拦截器链的postHandle方法
  • 执行拦截器链的afterCompletion方法

执行结果如下

/testJson----------------------preHandletestJson/testJson----------------------postHandle/testJson----------------------afterCompletion

香烟价格网