SpringMVC源码分析

又是美好的一天呀~
个人博客地址: huanghong.top

本文预估阅读时长为40分钟左右~

本文关联文章 Spring全局异常处理的使用及源码分析

SpringMVC源码分析

执行链路图

在这里插入图片描述

初始化

项目初始化并不会直接初始化WebApplicationContext,当服务端第一次接收到客户端请求时,进行Servlet初始化。

init

//javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

initServletBean

//org.springframework.web.servlet.FrameworkServlet#initServletBean
protected final void initServletBean() throws ServletException {
   getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
   if (logger.isInfoEnabled()) {
      logger.info("Initializing Servlet '" + getServletName() + "'");
   }
   long startTime = System.currentTimeMillis();

   try {
      //执行web上下文初始化
      this.webApplicationContext = initWebApplicationContext();
      initFrameworkServlet();
   }
   catch (ServletException | RuntimeException ex) {
      logger.error("Context initialization failed", ex);
      throw ex;
   }

   if (logger.isDebugEnabled()) {
      String value = this.enableLoggingRequestDetails ?
            "shown which may lead to unsafe logging of potentially sensitive data" :
            "masked to prevent unsafe logging of potentially sensitive data";
      logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +
            "': request parameters and headers will be " + value);
   }

   if (logger.isInfoEnabled()) {
      logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
   }
}

DispatcherServlet.properties

org\springframework\spring-webmvc\5.3.13\spring-webmvc-5.3.13.jar!\org\springframework\web\servlet\DispatcherServlet.properties

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
   org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
   org.springframework.web.servlet.function.support.RouterFunctionMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
   org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
   org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
   org.springframework.web.servlet.function.support.HandlerFunctionAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
   org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
   org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

onRefresh

//org.springframework.web.servlet.DispatcherServlet#onRefresh
protected void onRefresh(ApplicationContext context) {
   initStrategies(context);
}

//org.springframework.web.servlet.DispatcherServlet#initStrategies
protected void initStrategies(ApplicationContext context) {
    //初始化文件上传解析器
    //默认赋值 org.springframework.web.multipart.support.StandardServletMultipartResolver
    initMultipartResolver(context);
    //初始化国际化语言解析器
    //默认赋值 org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
    initLocaleResolver(context);
    //初始化主题解析器
    //默认赋值 org.springframework.web.servlet.theme.FixedThemeResolver
    initThemeResolver(context);
    //初始化处理映射器
    initHandlerMappings(context);
    //初始化处理适配器
    initHandlerAdapters(context);
    //初始化异常处理解析器(@ControllerAdvice)
    //默认赋值 org.springframework.web.servlet.HandlerExceptionResolver接口子类
    //具体解析步骤
    initHandlerExceptionResolvers(context);
    //初始化视图转换器
    //默认赋值 org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
    initRequestToViewNameTranslator(context);
    //初始化视图解析器
    //默认赋值 org.springframework.web.servlet.ViewResolver接口子类
    initViewResolvers(context);
    //初始化flash管理器
    //默认赋值 org.springframework.web.servlet.support.SessionFlashMapManager
    initFlashMapManager(context);
}

initHandlerMappings

//org.springframework.web.servlet.DispatcherServlet#initHandlerMappings
private void initHandlerMappings(ApplicationContext context) {
   this.handlerMappings = null;

   //是否检查所有处理器映射器 包含父类中的上下文
   if (this.detectAllHandlerMappings) {
      // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
      //获取全局上下文所有的处理器映射器
      Map<String, HandlerMapping> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
      //处理器映射器结果集不为空
      if (!matchingBeans.isEmpty()) {
         //赋值
         this.handlerMappings = new ArrayList<>(matchingBeans.values());
         // We keep HandlerMappings in sorted order.
         //排序
         AnnotationAwareOrderComparator.sort(this.handlerMappings);
      }
   }
   else {
      try {
         //没有手动配置则为空,后续会添加一个默认的处理器映射器
         HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
         this.handlerMappings = Collections.singletonList(hm);
      }
      catch (NoSuchBeanDefinitionException ex) {
         // Ignore, we'll add a default HandlerMapping later.
      }
   }

   // Ensure we have at least one HandlerMapping, by registering
   // a default HandlerMapping if no other mappings are found.
   //如果处理器映射器为空
   if (this.handlerMappings == null) {
      //获取默认值 
      this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
      if (logger.isTraceEnabled()) {
         logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
               "': using default strategies from DispatcherServlet.properties");
      }
   }
   //遍历处理器映射器结果集
   for (HandlerMapping mapping : this.handlerMappings) {
      //存在处理器映射器使用路径解析模式则赋值parseRequestPath为true
      if (mapping.usesPathPatterns()) {
         this.parseRequestPath = true;
         break;
      }
   }
}

//org.springframework.web.servlet.handler.AbstractHandlerMapping#usesPathPatterns
public boolean usesPathPatterns() {
    return getPatternParser() != null;
}

默认加载的HandlerMapping(5个)

  1. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerMapping(order:0)

  2. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#beanNameHandlerMapping(order:2)

  3. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#routerFunctionMapping(order:3)

  4. org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry#getHandlerMapping

    -> SimpleUrlHandlerMapping(order:Ordered.LOWEST_PRECEDENCE - 1)

  5. org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration#welcomePageHandlerMapping(order:Ordered.LOWEST_PRECEDENCE)

    继承org.springframework.web.servlet.handler.AbstractHandlerMapping的order属性

getDefaultStrategies

//org.springframework.web.servlet.DispatcherServlet#getDefaultStrategies
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
   if (defaultStrategies == null) {
      try {
         // Load default strategy implementations from properties file.
         // This is currently strictly internal and not meant to be customized
         // by application developers.
         //加载DispatcherServlet同级包中的DispatcherServlet.properties
         ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
         defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
      }
      catch (IOException ex) {
         throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
      }
   }
   //获取接口名作为key
   String key = strategyInterface.getName();
   //在DispatcherServlet.properties中获取对应的value值
   String value = defaultStrategies.getProperty(key);
   if (value != null) {
      String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
      List<T> strategies = new ArrayList<>(classNames.length);
      for (String className : classNames) {
         try {
            //通过反射构建对应类型对象实例并添加进策略中
            Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
            Object strategy = createDefaultStrategy(context, clazz);
            strategies.add((T) strategy);
         }
         catch (ClassNotFoundException ex) {
            throw new BeanInitializationException(
                  "Could not find DispatcherServlet's default strategy class [" + className +
                  "] for interface [" + key + "]", ex);
         }
         catch (LinkageError err) {
            throw new BeanInitializationException(
                  "Unresolvable class definition for DispatcherServlet's default strategy class [" +
                  className + "] for interface [" + key + "]", err);
         }
      }
      return strategies;
   }
   else {
      return Collections.emptyList();
   }
}

initHandlerAdapters

//org.springframework.web.servlet.DispatcherServlet#initHandlerAdapters
private void initHandlerAdapters(ApplicationContext context) {
   this.handlerAdapters = null;
   //是否检查所有处理器适配器 包含父类中的上下文
   if (this.detectAllHandlerAdapters) {
      // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
      //获取全局上下文所有的处理器适配器
      Map<String, HandlerAdapter> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
       //处理器适配器结果集不为空
      if (!matchingBeans.isEmpty()) {
         //赋值
         this.handlerAdapters = new ArrayList<>(matchingBeans.values());
         // We keep HandlerAdapters in sorted order.
         //排序
         AnnotationAwareOrderComparator.sort(this.handlerAdapters);
      }
   }
   else {
      try {
         //没有手动配置则为空,后续会添加一个默认的处理器适配器
         HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
         this.handlerAdapters = Collections.singletonList(ha);
      }
      catch (NoSuchBeanDefinitionException ex) {
         // Ignore, we'll add a default HandlerAdapter later.
      }
   }

   // Ensure we have at least some HandlerAdapters, by registering
   // default HandlerAdapters if no other adapters are found.
   //如果处理器适配器为空
   if (this.handlerAdapters == null) {
      //获取默认值
      this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
      if (logger.isTraceEnabled()) {
         logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
               "': using default strategies from DispatcherServlet.properties");
      }
   }
}

默认加载的HandlerAdapter(4个)

  1. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter
  2. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#handlerFunctionAdapter
  3. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#httpRequestHandlerAdapter
  4. org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#simpleControllerHandlerAdapter

doService

HTTP请求处理链路

  1. 客户端HTTP请求
  2. tomcat起一个线程负责处理请求
  3. ApplicationFilterChain#internalDoFilter过滤器链处理请求
  4. HttpServlet#service处理请求
  5. org.springframework.web.servlet.DispatcherServlet#doService
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
   //日志记录
   logRequest(request);

   //保存原request属性,用于请求执行完属性清理后的属性恢复
   Map<String, Object> attributesSnapshot = null;
   if (WebUtils.isIncludeRequest(request)) {
      attributesSnapshot = new HashMap<>();
      Enumeration<?> attrNames = request.getAttributeNames();
      while (attrNames.hasMoreElements()) {
         String attrName = (String) attrNames.nextElement();
         //是否开启属性清理功能  or 属性名的前缀为org.springframework.web.servlet
         if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
            //放入缓存中
            attributesSnapshot.put(attrName, request.getAttribute(attrName));
         }
      }
   }

   //设置MVC相关资源属性 用于后续请求过程的处理
   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());

   //设置flash管理器属性
   if (this.flashMapManager != null) {
      FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
      if (inputFlashMap != null) {
         request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
      }
      request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
      request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
   }

   //是否进行路径解析(默认不进行)
   RequestPath previousRequestPath = null;
   if (this.parseRequestPath) {
      previousRequestPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
      ServletRequestPathUtils.parseAndCache(request);
   }

   try {
      //逻辑处理
      doDispatch(request, response);
   }
   finally {
      //request属性恢复
      if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
         // Restore the original attribute snapshot, in case of an include.
         if (attributesSnapshot != null) {
            restoreAttributesAfterInclude(request, attributesSnapshot);
         }
      }
      //原request请求路径恢复
      if (this.parseRequestPath) {
         ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
      }
   }
}

doDispatch

//org.springframework.web.servlet.DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   HttpServletRequest processedRequest = request;
   HandlerExecutionChain mappedHandler = null;
   //多文档类型请求
   boolean multipartRequestParsed = false;
   //web异步处理管理
   WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

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

      try {
         //检查是否为多文档类型请求 检查请求头中的Content-Type属性是否为multipart/form-data or multipart/开头
         //若为多文档类型请求则构建一个StandardMultipartHttpServletRequest对象
         processedRequest = checkMultipart(request);
         multipartRequestParsed = (processedRequest != request);

         //为当前request选择一个处理器,维护了一个最适配的HandlerMethod和对应的拦截器链
         mappedHandler = getHandler(processedRequest);
         if (mappedHandler == null) {
            //没有找到对应的处理器,返回404
            noHandlerFound(processedRequest, response);
            return;
         }

         //为当前request选择一个处理器适配器
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

         //如果是GET或HEAD请求
         String method = request.getMethod();
         boolean isGet = HttpMethod.GET.matches(method);
         if (isGet || HttpMethod.HEAD.matches(method)) {
            //获取最后修改时间
            long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
            //调用checkNotModified方法验证 http 请求头中的“If-Modified-Since”的时间进行对比,判断页面是否更新过。
            //如果有更新才执行具体的Controller, 没有更新则响应304状态码信息(HTTP 304: Not Modified )
            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;
         }
		 //使用默认的视图页面 mv不为null && 没有对应视图则使用默认视图
         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);
      }
      //进行页面跳转和视图渲染
      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 {
         //文档类型请求清除所有request属性资源
         if (multipartRequestParsed) {
            cleanupMultipart(processedRequest);
         }
      }
   }
}

getHandler

//org.springframework.web.servlet.DispatcherServlet#getHandler
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   if (this.handlerMappings != null) {
      //遍历处理器映射器 默认由优先级最高的requestMappingHandlerMapping来进行处理
      for (HandlerMapping mapping : this.handlerMappings) {
         //获取处理器
         //HandlerExecutionChain包含HandlerMethod和Interceptors拦截器链
         HandlerExecutionChain handler = mapping.getHandler(request);
         if (handler != null) {
            //处理器不为空则返回
            return handler;
         }
      }
   }
   return null;
}

getHandler

//org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   //获取URI最合适的HandlerMethod
   Object handler = getHandlerInternal(request);
   //handler为空获取默认的处理器 默认的handler也为null
   if (handler == null) {
      handler = getDefaultHandler();
   }
   //handler为空直接返回
   if (handler == null) {
      return null;
   }
   //handler如果是字符串对象,则通过上下文获取Handler实例
   if (handler instanceof String) {
      String handlerName = (String) handler;
      handler = obtainApplicationContext().getBean(handlerName);
   }

   //确保存在缓存请求路径
   if (!ServletRequestPathUtils.hasCachedPath(request)) {
      //否则初始化请求路径
      initLookupPath(request);
   }
   //获取封装拦截器链后的HandlerMethod对象
   HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

   if (logger.isTraceEnabled()) {
      logger.trace("Mapped to " + handler);
   }
   else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) {
      logger.debug("Mapped to " + executionChain.getHandler());
   }
   //跨域处理
   if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
      CorsConfiguration config = getCorsConfiguration(handler, request);
      if (getCorsConfigurationSource() != null) {
         CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
         config = (globalConfig != null ? globalConfig.combine(config) : config);
      }
      if (config != null) {
         config.validateAllowCredentials();
      }
      executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
   }

   return executionChain;
}

getHandlerInternal

//org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#getHandlerInternal
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
   //getPathWithinApplication获取contextPath + requestUri 
   String lookupPath = initLookupPath(request);
   this.mappingRegistry.acquireReadLock();
   try {
      //获取URI最合适的HandlerMethod
      HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
      return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
   }
   finally {
      this.mappingRegistry.releaseReadLock();
   }
}

lookupHandlerMethod

//org.springframework.web.servlet.handler.AbstractHandlerMethodMapping#lookupHandlerMethod
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
   List<Match> matches = new ArrayList<>();
   //获取uri对应RequestInfoMapping对象集合
   List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
   if (directPathMatches != null) {
      //获取uri对应HandlerMethod包装对象,放入本地缓存
      addMatchingMappings(directPathMatches, matches, request);
   }
   if (matches.isEmpty()) {
      addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
   }
   if (!matches.isEmpty()) {
      //获取最适配的HandlerMethod包装类
      Match bestMatch = matches.get(0);
      if (matches.size() > 1) {
         //HandlerMethod包装类数量大于1的话进行排序后取第一个HandlerMethod包装类(请求条件数量更多的优先-TODO)
         Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
         matches.sort(comparator);
         bestMatch = matches.get(0);
         if (logger.isTraceEnabled()) {
            logger.trace(matches.size() + " matching mappings: " + matches);
         }
         //跨域请求处理
         if (CorsUtils.isPreFlightRequest(request)) {
            for (Match match : matches) {
               if (match.hasCorsConfig()) {
                  return PREFLIGHT_AMBIGUOUS_MATCH;
               }
            }
         }
         else {
            //抛出排序同级异常
            Match secondBestMatch = matches.get(1);
            if (comparator.compare(bestMatch, secondBestMatch) == 0) {
               Method m1 = bestMatch.getHandlerMethod().getMethod();
               Method m2 = secondBestMatch.getHandlerMethod().getMethod();
               String uri = request.getRequestURI();
               throw new IllegalStateException(
                     "Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
            }
         }
      }
      //设置HandlerMethod的request属性
      request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
      //路径变量处理
      handleMatch(bestMatch.mapping, lookupPath, request);
      //返回HandlerMethod
      return bestMatch.getHandlerMethod();
   }
   else {
      return handleNoMatch(this.mappingRegistry.getRegistrations().keySet(), lookupPath, request);
   }
}

getHandlerExecutionChain

//org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
   //封装HandlerExecutionChain对象
   HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
         (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
   for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
      //Spring内部维护的一个url匹配拦截器
      if (interceptor instanceof MappedInterceptor) {
         MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
         if (mappedInterceptor.matches(request)) {
            chain.addInterceptor(mappedInterceptor.getInterceptor());
         }
      }
      else {
         //添加拦截器
         chain.addInterceptor(interceptor);
      }
   }
   return chain;
}

getHandlerAdapter

//org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
   if (this.handlerAdapters != null) {
      for (HandlerAdapter adapter : this.handlerAdapters) {
         //(handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler))  supportsInternal返回true
         //返回默认RequestMappingHandlerAdapter
         if (adapter.supports(handler)) {
            return adapter;
         }
      }
   }
   throw new ServletException("No adapter for handler [" + handler +
         "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

applyPreHandle

//org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
   for (int i = 0; i < this.interceptorList.size(); i++) {
      HandlerInterceptor interceptor = this.interceptorList.get(i);
      //拦截器前置处理
      if (!interceptor.preHandle(request, response, this.handler)) {
         //前置处理返回false 则执行拦截器中的afterCompletion方法
         triggerAfterCompletion(request, response, null);
         return false;
      }
      this.interceptorIndex = i;
   }
   return true;
}

handleInternal

//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
protected ModelAndView handleInternal(HttpServletRequest request,
      HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
   ModelAndView mav;
   //检查请求中所支持的方法和是否需要session
   checkRequest(request);

   //是否需要基于session来执行加锁执行
   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
         //session为null 直接执行
         mav = invokeHandlerMethod(request, response, handlerMethod);
      }
   }
   else {
      //直接执行HandlerMethod
      mav = invokeHandlerMethod(request, response, handlerMethod);
   }
   //响应头中不包含Cache-Control,响应缓存处理
   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#invokeHandlerMethod
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
      HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
   //构建一个ServletWebRequest对象
   ServletWebRequest webRequest = new ServletWebRequest(request, response);
   try {
      //WebDataBinderFactory为目标对象创建一个WebDataBinder实例
	  //WebDataBinder继承了DataBinder类,为web请求提供了参数绑定服务
      WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
      //获取ModelFactory
      ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
	  // 创建ServletInvocableHandlerMethod对象 ServletInvocableHandlerMethod继承并扩展了InvocableHandlerMethod
      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,并初始化Model对象
      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;
      }
	  //返回ModelAndView or null
      return getModelAndView(mavContainer, modelFactory, webRequest);
   }
   finally {
      //请求结束回调
      webRequest.requestCompleted();
   }
}

invokeAndHandle

//org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
      Object... providedArgs) throws Exception {
   //执行请求
   Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
   //设置response响应参数
   setResponseStatus(webRequest);
   //请求返回结果值为空
   if (returnValue == null) {
      //request类型为not modified || 返回参数不为空 || 请求是否被完整处理
      if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
         //如果是not modified类型请求则进行缓存失效
         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 {
      //处理返回结果集 RequestResponseBodyMethodProcessor处理ResponseBody结果集
      this.returnValueHandlers.handleReturnValue(
            returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
   }
   catch (Exception ex) {
      if (logger.isTraceEnabled()) {
         logger.trace(formatErrorForReturnValue(returnValue), ex);
      }
      throw ex;
   }
}

invokeForRequest

//org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public 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);
}

getModelAndView

//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getModelAndView
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
      ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {

   modelFactory.updateModel(webRequest, mavContainer);
   //请求被完整处理
   if (mavContainer.isRequestHandled()) {
      //返回null
      return null;
   }
   //获取ModelMap
   ModelMap model = mavContainer.getModel();
   //获取ModelAndView对象 封装请求对应视图和数据
   ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
   if (!mavContainer.isViewReference()) {
      //设置视图
      mav.setView((View) mavContainer.getView());
   }
   //flash属性填充
   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;
}

processDispatchResult

//org.springframework.web.servlet.DispatcherServlet#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异常处理
      if (exception instanceof ModelAndViewDefiningException) {
         logger.debug("ModelAndViewDefiningException encountered", exception);
         mv = ((ModelAndViewDefiningException) exception).getModelAndView();
      }
      else {
         //其他异常处理
         Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
         //异常处理
         mv = processHandlerException(request, response, handler, exception);
         errorView = (mv != null);
      }
   }

   //视图渲染
   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) {
      //拦截器的请求完成之后的处理
      mappedHandler.triggerAfterCompletion(request, response, null);
   }
}

备注

  • HandlerMethod注册逻辑(org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.MappingRegistry#register)

感谢阅读完本篇文章!!!
个人博客地址: huanghong.top

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢正常冰的冰美式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值