springmvc源码解析之DispatcherServlet二

说在前面

本次主要介绍DispatcherServlet,更多精彩请关注”天河聊架构“微信公众号。

 

springmvc配置解析

找到这个方法org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain

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) {
         if (interceptor instanceof MappedInterceptor) {
            MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
            if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
               chain.addInterceptor(mappedInterceptor.getInterceptor());
            }
         }
         else {
            chain.addInterceptor(interceptor);
         }
      }
      return chain;
   }

往上返回到这个方法org.springframework.web.cors.UrlBasedCorsConfigurationSource#getCorsConfiguration

@Override
   public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
//    获取请求路径 -》
      String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
      for (Map.Entry<String, CorsConfiguration> entry : this.corsConfigurations.entrySet()) {
         if (this.pathMatcher.match(entry.getKey(), lookupPath)) {
            return entry.getValue();
         }
      }
      return null;
   }

进入到这个方法org.springframework.web.util.UrlPathHelper#getLookupPathForRequest

public String getLookupPathForRequest(HttpServletRequest request) {
   // Always use full path within current servlet context? 总是在当前servlet上下文中使用完整路径? -》
   if (this.alwaysUseFullPath) {
      return getPathWithinApplication(request);
   }
   // Else, use path within current servlet mapping if applicable 否则,在当前servlet映射中使用path(如果适用)
   String rest = getPathWithinServletMapping(request);
   if (!"".equals(rest)) {
      return rest;
   }
   else {
      return getPathWithinApplication(request);
   }
}

这里前面介绍过了。

往上返回到这个方法org.springframework.web.servlet.handler.AbstractHandlerMapping#getCorsConfiguration

protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) {
      Object resolvedHandler = handler;
      if (handler instanceof HandlerExecutionChain) {
         resolvedHandler = ((HandlerExecutionChain) handler).getHandler();
      }
      if (resolvedHandler instanceof CorsConfigurationSource) {
//       获取跨域配置 -》
         return ((CorsConfigurationSource) resolvedHandler).getCorsConfiguration(request);
      }
      return null;
   }

进入到这个方法org.springframework.web.servlet.handler.HandlerMappingIntrospector#getCorsConfiguration

@Override
   public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
      Assert.notNull(this.handlerMappings, "Handler mappings not initialized");
      HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
      for (HandlerMapping handlerMapping : this.handlerMappings) {
         HandlerExecutionChain handler = null;
         try {
//          获取handler -》
            handler = handlerMapping.getHandler(wrapper);
         }
         catch (Exception ex) {
            // Ignore
         }
         if (handler == null) {
            continue;
         }
         if (handler.getInterceptors() != null) {
            for (HandlerInterceptor interceptor : handler.getInterceptors()) {
               if (interceptor instanceof CorsConfigurationSource) {
                  return ((CorsConfigurationSource) interceptor).getCorsConfiguration(wrapper);
               }
            }
         }
         if (handler.getHandler() instanceof CorsConfigurationSource) {
            return ((CorsConfigurationSource) handler.getHandler()).getCorsConfiguration(wrapper);
         }
      }
      return null;
   }

往上返回到这个方法org.springframework.web.servlet.handler.AbstractHandlerMapping#getCorsHandlerExecutionChain

protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
         HandlerExecutionChain chain, CorsConfiguration config) {
//    -》
      if (CorsUtils.isPreFlightRequest(request)) {
//       获取执行链上的拦截器
         HandlerInterceptor[] interceptors = chain.getInterceptors();
         chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
      }
      else {
//       添加CorsInterceptor
         chain.addInterceptor(new CorsInterceptor(config));
      }
      return chain;
   }

进入到这个方法org.springframework.web.cors.CorsUtils#isPreFlightRequest

public static boolean isPreFlightRequest(HttpServletRequest request) {
   return (isCorsRequest(request) && HttpMethod.OPTIONS.matches(request.getMethod()) &&
         request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);
}

往上返回到这个方法org.springframework.web.servlet.DispatcherServlet#noHandlerFound

protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
   if (pageNotFoundLogger.isWarnEnabled()) {
      pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) +
            "] in DispatcherServlet with name '" + getServletName() + "'");
   }
   if (this.throwExceptionIfNoHandlerFound) {
      throw new NoHandlerFoundException(request.getMethod(), getRequestUri(request),
            new ServletServerHttpRequest(request).getHeaders());
   }
   else {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
   }
}

往上返回到这个方法org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
   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");
}

往上返回到这个方法org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
//    获取hander的拦截器 -》
      HandlerInterceptor[] interceptors = getInterceptors();
      if (!ObjectUtils.isEmpty(interceptors)) {
         for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];
//          执行拦截器的前置处理方法
            if (!interceptor.preHandle(request, response, this.handler)) {
//             出发执行完成事件 -》
               triggerAfterCompletion(request, response, null);
               return false;
            }
            this.interceptorIndex = i;
         }
      }
      return true;
   }

进入到这个方法org.springframework.web.servlet.HandlerExecutionChain#getInterceptors

public HandlerInterceptor[] getInterceptors() {
   if (this.interceptors == null && this.interceptorList != null) {
      this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
   }
   return this.interceptors;
}

往上返回到这个方法org.springframework.web.servlet.HandlerExecutionChain#triggerAfterCompletion

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

进入到这个方法org.springframework.web.servlet.HandlerExecutionChain#getInterceptors

public HandlerInterceptor[] getInterceptors() {
   if (this.interceptors == null && this.interceptorList != null) {
      this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
   }
   return this.interceptors;
}

往上返回到这个方法org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle默认实现方法执行

@Override
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {

   return handleInternal(request, response, (HandlerMethod) handler);
}

进入到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

@Override
   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) {
//             执行handler的业务方法 @RequestMapping标准的方法 -》
               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;
   }

进入到这个方法org.springframework.web.servlet.support.WebContentGenerator#checkRequest

protected final void checkRequest(HttpServletRequest request) throws ServletException {
      // Check whether we should support the request method.
      String method = request.getMethod();
//    请求方法不支持
      if (this.supportedMethods != null && !this.supportedMethods.contains(method)) {
         throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods);
      }

      // Check whether a session is required. 检查session
      if (this.requireSession && request.getSession(false) == null) {
         throw new HttpSessionRequiredException("Pre-existing session required but none found");
      }
   }

往上返回到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod

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

      ServletWebRequest webRequest = new ServletWebRequest(request, response);
      try {
//       根据业务handler方法获取web数据绑定工厂 -》
         WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
//       获取ModelFactory -》
         ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
         ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
//       设置执行方法的参数解析器
         invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
//       设置执行方法的返回值解析器
         invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
         invocableMethod.setDataBinderFactory(binderFactory);
         invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
//       创建modelAndView容器
         ModelAndViewContainer mavContainer = new ModelAndViewContainer();
         mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
//       初始化model -》
         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();
            if (logger.isDebugEnabled()) {
               logger.debug("Found concurrent result value [" + result + "]");
            }
            invocableMethod = invocableMethod.wrapConcurrentResult(result);
         }

//       执行方法 -》
         invocableMethod.invokeAndHandle(webRequest, mavContainer);
//       如果是异步请求,同步返回null
         if (asyncManager.isConcurrentHandlingStarted()) {
            return null;
         }
//       返回ModelAndView -》
         return getModelAndView(mavContainer, modelFactory, webRequest);
      }
      finally {
//       请求完成-》
         webRequest.requestCompleted();
      }
   }

进入到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDataBinderFactory

private WebDataBinderFactory getDataBinderFactory(HandlerMethod handlerMethod) throws Exception {
//    获取业务方法的handler类型
      Class<?> handlerType = handlerMethod.getBeanType();
//    根据业务handler类型获取方法
      Set<Method> methods = this.initBinderCache.get(handlerType);
      if (methods == null) {
//       查询业务handler的方法有@InitBinder注解的方法
         methods = MethodIntrospector.selectMethods(handlerType, INIT_BINDER_METHODS);
         this.initBinderCache.put(handlerType, methods);
      }
      List<InvocableHandlerMethod> initBinderMethods = new ArrayList<InvocableHandlerMethod>();
      // Global methods first
      for (Entry<ControllerAdviceBean, Set<Method>> entry : this.initBinderAdviceCache.entrySet()) {
//       检查业务handler上面是否有@ControllerAdvice注解
         if (entry.getKey().isApplicableToBeanType(handlerType)) {
            Object bean = entry.getKey().resolveBean();
            for (Method method : entry.getValue()) {
//             创建InitBinderMethod -》
               initBinderMethods.add(createInitBinderMethod(bean, method));
            }
         }
      }
      for (Method method : methods) {
         Object bean = handlerMethod.getBean();
         initBinderMethods.add(createInitBinderMethod(bean, method));
      }
      return createDataBinderFactory(initBinderMethods);
   }

   private InvocableHandlerMethod createInitBinderMethod(Object bean, Method method) {
      InvocableHandlerMethod binderMethod = new InvocableHandlerMethod(bean, method);
//    设置initBinder的参数解析器
      binderMethod.setHandlerMethodArgumentResolvers(this.initBinderArgumentResolvers);
      binderMethod.setDataBinderFactory(new DefaultDataBinderFactory(this.webBindingInitializer));
      binderMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
      return binderMethod;
   }

进入到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#createInitBinderMethod

private InvocableHandlerMethod createInitBinderMethod(Object bean, Method method) {
      InvocableHandlerMethod binderMethod = new InvocableHandlerMethod(bean, method);
//    设置initBinder的参数解析器
      binderMethod.setHandlerMethodArgumentResolvers(this.initBinderArgumentResolvers);
      binderMethod.setDataBinderFactory(new DefaultDataBinderFactory(this.webBindingInitializer));
      binderMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
      return binderMethod;
   }

往上返回到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getModelFactory

private ModelFactory getModelFactory(HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) {
//    获取有@SessionAttribute注解的handler -》
      SessionAttributesHandler sessionAttrHandler = getSessionAttributesHandler(handlerMethod);
      Class<?> handlerType = handlerMethod.getBeanType();
      Set<Method> methods = this.modelAttributeCache.get(handlerType);
      if (methods == null) {
//       获取handler中有@RequestMapping、@ModelAttribute的方法
         methods = MethodIntrospector.selectMethods(handlerType, MODEL_ATTRIBUTE_METHODS);
         this.modelAttributeCache.put(handlerType, methods);
      }
      List<InvocableHandlerMethod> attrMethods = new ArrayList<InvocableHandlerMethod>();
      // Global methods first
      for (Entry<ControllerAdviceBean, Set<Method>> entry : this.modelAttributeAdviceCache.entrySet()) {
//       如果handler上有@ControllerAdvice -》
         if (entry.getKey().isApplicableToBeanType(handlerType)) {
            Object bean = entry.getKey().resolveBean();
            for (Method method : entry.getValue()) {
//             创建ModelAttributeMethod -》
               attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
            }
         }
      }
      for (Method method : methods) {
         Object bean = handlerMethod.getBean();
         attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
      }
      return new ModelFactory(attrMethods, binderFactory, sessionAttrHandler);
   }

进入到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getSessionAttributesHandler

private SessionAttributesHandler getSessionAttributesHandler(HandlerMethod handlerMethod) {
      Class<?> handlerType = handlerMethod.getBeanType();
//    从缓存中获取SessionAttributesHandler
      SessionAttributesHandler sessionAttrHandler = this.sessionAttributesHandlerCache.get(handlerType);
      if (sessionAttrHandler == null) {
         synchronized (this.sessionAttributesHandlerCache) {
            sessionAttrHandler = this.sessionAttributesHandlerCache.get(handlerType);
            if (sessionAttrHandler == null) {
               sessionAttrHandler = new SessionAttributesHandler(handlerType, sessionAttributeStore);
               this.sessionAttributesHandlerCache.put(handlerType, sessionAttrHandler);
            }
         }
      }
      return sessionAttrHandler;
   }

进入到这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#createModelAttributeMethod

private InvocableHandlerMethod createModelAttributeMethod(WebDataBinderFactory factory, Object bean, Method method) {
      InvocableHandlerMethod attrMethod = new InvocableHandlerMethod(bean, method);
//    设置参数解析器
      attrMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
      attrMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
      attrMethod.setDataBinderFactory(factory);
      return attrMethod;
   }

往上返回到这个方法org.springframework.web.method.annotation.ModelFactory#initModel

public void initModel(NativeWebRequest request, ModelAndViewContainer container, HandlerMethod handlerMethod)
         throws Exception {

//    从session中获取属性值 -》
      Map<String, ?> sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request);
//    合并session参数 -》
      container.mergeAttributes(sessionAttributes);
//    执行有@ModelAttribute的方法 -》
      invokeModelAttributeMethods(request, container);
//    查找handle方法上@ModelAttribute的参数 -》
      for (String name : findSessionAttributeArguments(handlerMethod)) {
         if (!container.containsAttribute(name)) {
            Object value = this.sessionAttributesHandler.retrieveAttribute(request, name);
            if (value == null) {
               throw new HttpSessionRequiredException("Expected session attribute '" + name + "'", name);
            }
            container.addAttribute(name, value);
         }
      }
   }

进入这个方法org.springframework.web.method.annotation.SessionAttributesHandler#retrieveAttributes

public Map<String, Object> retrieveAttributes(WebRequest request) {
   Map<String, Object> attributes = new HashMap<String, Object>();
   for (String name : this.knownAttributeNames) {
      Object value = this.sessionAttributeStore.retrieveAttribute(request, name);
      if (value != null) {
         attributes.put(name, value);
      }
   }
   return attributes;
}

往上返回这个方法org.springframework.web.method.support.ModelAndViewContainer#mergeAttributes

public ModelAndViewContainer mergeAttributes(Map<String, ?> attributes) {
//    -》
      getModel().mergeAttributes(attributes);
      return this;
   }

进入这个方法org.springframework.web.method.support.ModelAndViewContainer#getModel

public ModelMap getModel() {
      if (useDefaultModel()) {
         return this.defaultModel;
      }
      else {
         if (this.redirectModel == null) {
//          model就是一个linkedHashMap
            this.redirectModel = new ModelMap();
         }
         return this.redirectModel;
      }
   }

往上返回到这个方法org.springframework.web.method.annotation.ModelFactory#invokeModelAttributeMethods

private void invokeModelAttributeMethods(NativeWebRequest request, ModelAndViewContainer container)
         throws Exception {

      while (!this.modelMethods.isEmpty()) {
         InvocableHandlerMethod modelMethod = getNextModelMethod(container).getHandlerMethod();
         ModelAttribute ann = modelMethod.getMethodAnnotation(ModelAttribute.class);
         if (container.containsAttribute(ann.name())) {
            if (!ann.binding()) {
               container.setBindingDisabled(ann.name());
            }
            continue;
         }

//       执行请求 -》
         Object returnValue = modelMethod.invokeForRequest(request, container);
         if (!modelMethod.isVoid()){
//          根据返回值和返回值类型获取返回值解析器 -》
            String returnValueName = getNameForReturnValue(returnValue, modelMethod.getReturnType());
            if (!ann.binding()) {
               container.setBindingDisabled(returnValueName);
            }
//          modelAndView容器不包含这个返回值就添加
            if (!container.containsAttribute(returnValueName)) {
               container.addAttribute(returnValueName, returnValue);
            }
         }
      }
   }

进入这个方法org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
         Object... providedArgs) throws Exception {

//    解析请求参数值 -》
      Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
               "' with arguments " + Arrays.toString(args));
      }
//    执行方法
      Object returnValue = doInvoke(args);
      if (logger.isTraceEnabled()) {
         logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
               "] returned [" + returnValue + "]");
      }
      return returnValue;
   }

进入这个方法org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues

private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,
         Object... providedArgs) throws Exception {

      MethodParameter[] parameters = getMethodParameters();
      Object[] args = new Object[parameters.length];
      for (int i = 0; i < parameters.length; i++) {
         MethodParameter parameter = parameters[i];
         parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
         args[i] = resolveProvidedArgument(parameter, providedArgs);
         if (args[i] != null) {
            continue;
         }
         if (this.argumentResolvers.supportsParameter(parameter)) {
            try {
//             解析参数 -》
               args[i] = this.argumentResolvers.resolveArgument(
                     parameter, mavContainer, request, this.dataBinderFactory);
               continue;
            }
            catch (Exception ex) {
               if (logger.isDebugEnabled()) {
                  logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex);
               }
               throw ex;
            }
         }
         if (args[i] == null) {
            throw new IllegalStateException("Could not resolve method parameter at index " +
                  parameter.getParameterIndex() + " in " + parameter.getMethod().toGenericString() +
                  ": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
         }
      }
      return args;
   }

进入这个方法org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#resolveArgument

@Override
   public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
         NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

//    根据参数获取参数解析器 -》
      HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
      if (resolver == null) {
         throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
      }
//    参数解析
      return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
   }

进入这个方法org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#getArgumentResolver

private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
      HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
      if (result == null) {
         for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
            if (logger.isTraceEnabled()) {
               logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
                     parameter.getGenericParameterType() + "]");
            }
//          方法参数解析器解析参数值
            if (methodArgumentResolver.supportsParameter(parameter)) {
               result = methodArgumentResolver;
               this.argumentResolverCache.put(parameter, result);
               break;
            }
         }
      }
      return result;
   }

往上返回到这个方法org.springframework.web.method.annotation.ModelFactory#getNameForReturnValue

public static String getNameForReturnValue(Object returnValue, MethodParameter returnType) {
//    获取返回值类型上的@ModelAttribute
      ModelAttribute ann = returnType.getMethodAnnotation(ModelAttribute.class);
      if (ann != null && StringUtils.hasText(ann.value())) {
         return ann.value();
      }
      else {
         Method method = returnType.getMethod();
         Class<?> containingClass = returnType.getContainingClass();
         Class<?> resolvedType = GenericTypeResolver.resolveReturnType(method, containingClass);
         return Conventions.getVariableNameForReturnType(method, resolvedType, returnValue);
      }
   }

往上返回这个方法org.springframework.web.method.annotation.ModelFactory#findSessionAttributeArguments

private List<String> findSessionAttributeArguments(HandlerMethod handlerMethod) {
      List<String> result = new ArrayList<String>();
      for (MethodParameter parameter : handlerMethod.getMethodParameters()) {
         if (parameter.hasParameterAnnotation(ModelAttribute.class)) {
//          获取@ModelAttribute配置的参数名称 -》
            String name = getNameForParameter(parameter);
            Class<?> paramType = parameter.getParameterType();
            if (this.sessionAttributesHandler.isHandlerSessionAttribute(name, paramType)) {
               result.add(name);
            }
         }
      }
      return result;
   }

进入这个方法org.springframework.web.method.annotation.ModelFactory#getNameForParameter

public static String getNameForParameter(MethodParameter parameter) {
   ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
   String name = (ann != null ? ann.value() : null);
   return (StringUtils.hasText(name) ? name : Conventions.getVariableNameForParameter(parameter));
}

往上返回到这个方法org.springframework.web.context.request.async.WebAsyncUtils#createAsyncWebRequest

public static AsyncWebRequest createAsyncWebRequest(HttpServletRequest request, HttpServletResponse response) {
   return (startAsyncAvailable ? AsyncWebRequestFactory.createStandardAsyncWebRequest(request, response) :
         new NoSupportAsyncWebRequest(request, response));
}

往上返回这个方法org.springframework.web.context.request.async.WebAsyncUtils#getAsyncManager(javax.servlet.ServletRequest)

public static WebAsyncManager getAsyncManager(ServletRequest servletRequest) {
      WebAsyncManager asyncManager = null;
//    从request中获取请求管理器
      Object asyncManagerAttr = servletRequest.getAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE);
      if (asyncManagerAttr instanceof WebAsyncManager) {
         asyncManager = (WebAsyncManager) asyncManagerAttr;
      }
//    如果没有就创建后绑定到request中
      if (asyncManager == null) {
         asyncManager = new WebAsyncManager();
         servletRequest.setAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE, asyncManager);
      }
      return asyncManager;
   }

往上返回这个方法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);
//    设置响应状态码 -》
      setResponseStatus(webRequest);
      if (returnValue == null) {
         if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
            mavContainer.setRequestHandled(true);
            return;
         }
      }
      else if (StringUtils.hasText(getResponseStatusReason())) {
         mavContainer.setRequestHandled(true);
         return;
      }

      mavContainer.setRequestHandled(false);
      try {
//       执行returnHandler -》
         this.returnValueHandlers.handleReturnValue(
               returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
      }
      catch (Exception ex) {
         if (logger.isTraceEnabled()) {
            logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
         }
         throw ex;
      }
   }

进入这个方法org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
         Object... providedArgs) throws Exception {

//    解析请求参数值 -》
      Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
               "' with arguments " + Arrays.toString(args));
      }
//    执行方法
      Object returnValue = doInvoke(args);
      if (logger.isTraceEnabled()) {
         logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
               "] returned [" + returnValue + "]");
      }
      return returnValue;
   }

这里前面介绍过了。

进入这个方法org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#setResponseStatus

private void setResponseStatus(ServletWebRequest webRequest) throws IOException {
   HttpStatus status = getResponseStatus();
   if (status == null) {
      return;
   }

   String reason = getResponseStatusReason();
   if (StringUtils.hasText(reason)) {
      webRequest.getResponse().sendError(status.value(), reason);
   }
   else {
      webRequest.getResponse().setStatus(status.value());
   }

   // To be picked up by RedirectView
   webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, status);
}

往上返回这个方法org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#handleReturnValue

@Override
   public void handleReturnValue(Object returnValue, MethodParameter returnType,
         ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

//    根据返回值和返回值类型找到handler -》
      HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
      if (handler == null) {
         throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
      }
//    根据returnHandler方法执行的结果包装最后要返回视图的值 -》
      handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
   }

进入到这个方法org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#selectHandler

private HandlerMethodReturnValueHandler selectHandler(Object value, MethodParameter returnType) {
//    是否是异步返回值
      boolean isAsyncValue = isAsyncReturnValue(value, returnType);
      for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
         if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
            continue;
         }
         if (handler.supportsReturnType(returnType)) {
            return handler;
         }
      }
      return null;
   }

往上返回这个方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getModelAndView

private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
         ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {

//    更新model -》
      modelFactory.updateModel(webRequest, mavContainer);
      if (mavContainer.isRequestHandled()) {
         return null;
      }
      ModelMap model = mavContainer.getModel();
//    创建modelAndView对象
      ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
//    是不是string的view视图
      if (!mavContainer.isViewReference()) {
         mav.setView((View) mavContainer.getView());
      }
      if (model instanceof RedirectAttributes) {
         Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
         HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
         RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
      }
      return mav;
   }

进入这个方法org.springframework.web.method.annotation.ModelFactory#updateModel

public void updateModel(NativeWebRequest request, ModelAndViewContainer container) throws Exception {
      ModelMap defaultModel = container.getDefaultModel();
      if (container.getSessionStatus().isComplete()){
         this.sessionAttributesHandler.cleanupAttributes(request);
      }
      else {
         this.sessionAttributesHandler.storeAttributes(request, defaultModel);
      }
      if (!container.isRequestHandled() && container.getModel() == defaultModel) {
//       更新绑定结果-》
         updateBindingResult(request, defaultModel);
      }
   }

进入这个方法org.springframework.web.method.annotation.ModelFactory#updateBindingResult

private void updateBindingResult(NativeWebRequest request, ModelMap model) throws Exception {
      List<String> keyNames = new ArrayList<String>(model.keySet());
      for (String name : keyNames) {
         Object value = model.get(name);
         if (isBindingCandidate(name, value)) {
            String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name;
            if (!model.containsAttribute(bindingResultKey)) {
//             创建数据绑定器-》
               WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name);
               model.put(bindingResultKey, dataBinder.getBindingResult());
            }
         }
      }
   }

进入到这个方法org.springframework.web.bind.support.DefaultDataBinderFactory#createBinder

@Override
   public final WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName)
         throws Exception {

//    创建数据绑定对象-》
      WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest);
      if (this.initializer != null) {
//       WebBindingInitializer初始化绑定器 -》
         this.initializer.initBinder(dataBinder, webRequest);
      }
//    初始化绑定器-》
      initBinder(dataBinder, webRequest);
      return dataBinder;
   }

进入这个方法org.springframework.web.method.annotation.InitBinderDataBinderFactory#initBinder

@Override
   public void initBinder(WebDataBinder dataBinder, NativeWebRequest request) throws Exception {
      for (InvocableHandlerMethod binderMethod : this.binderMethods) {
//       如果方法上有@InitBinder注解-》
         if (isBinderMethodApplicable(binderMethod, dataBinder)) {
//          执行请求-》
            Object returnValue = binderMethod.invokeForRequest(request, null, dataBinder);
            if (returnValue != null) {
               throw new IllegalStateException(
                     "@InitBinder methods must not return a value (should be void): " + binderMethod);
            }
         }
      }
   }

进入这个方法org.springframework.web.method.annotation.InitBinderDataBinderFactory#isBinderMethodApplicable

protected boolean isBinderMethodApplicable(HandlerMethod initBinderMethod, WebDataBinder dataBinder) {
   InitBinder ann = initBinderMethod.getMethodAnnotation(InitBinder.class);
   String[] names = ann.value();
   return (ObjectUtils.isEmpty(names) || ObjectUtils.containsElement(names, dataBinder.getObjectName()));
}

往上返回这个方法org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
         Object... providedArgs) throws Exception {

//    解析请求参数值 -》
      Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
               "' with arguments " + Arrays.toString(args));
      }
//    执行方法
      Object returnValue = doInvoke(args);
      if (logger.isTraceEnabled()) {
         logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
               "] returned [" + returnValue + "]");
      }
      return returnValue;
   }

这里前面介绍过了。

往上返回到这个方法org.springframework.web.context.request.AbstractRequestAttributes#requestCompleted

public void requestCompleted() {
//    执行请求回调
      executeRequestDestructionCallbacks();
//    更新session绑定参数
      updateAccessedSessionAttributes();
      this.requestActive = false;
   }

往上返回到这个方法org.springframework.web.servlet.DispatcherServlet#doDispatch这一行

// Actually invoke the handler.执行handler -》
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

 

说到最后

本次源码解析仅代表个人观点,仅供参考。

 

转载于:https://my.oschina.net/u/3775437/blog/3027253

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值