源码-springmvc初始化对Controller的处理

前言

基于Spring-5.2.5.RELEASE版本

1、分析controller中的方法调用的过程

DispatcherServlet

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   HttpServletRequest processedRequest = request;
   HandlerExecutionChain mappedHandler = null;
   boolean multipartRequestParsed = false;

   WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

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

      try {
         processedRequest = checkMultipart(request);
         multipartRequestParsed = (processedRequest != request);
		 // 获取handler和HandlerInterceptor,并组合到HandlerExecutionChain中
         mappedHandler = getHandler(processedRequest);
         // 没有找到对应的handler,直接返回前台404
         if (mappedHandler == null) {
            noHandlerFound(processedRequest, response);
            return;
         }
	     // 根据handler获取handlerAdapter(适配器模式)
         // 一般为RequestMappingHandlerAdapter这个类,这个类是对RequestMapping注解的支持 
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
		 
         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;
            }
         }
         // 调用拦截器的applyPreHandle方法,从第一个开始执行到最后一个
         if (!mappedHandler.applyPreHandle(processedRequest, response)) {
            return;
         }
		 // 开始调用RequestMappingHandlerAdapter父类AbstractHandlerMethodAdapter的handle方法
         // 最终调用RequestMappingHandlerAdapter的handleInternal方法
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

         if (asyncManager.isConcurrentHandlingStarted()) {
            return;
         }

         applyDefaultViewName(processedRequest, mv);
         // 调用拦截器的applyPostHandle方法,从最后一个开始执行到第一个
         mappedHandler.applyPostHandle(processedRequest, response, mv);
      }
      catch (Exception ex) {
         dispatchException = ex;
      }
      catch (Throwable err) {
         dispatchException = new NestedServletException("Handler dispatch failed", err);
      }
      processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
   }
   catch (Exception ex) {
      // 调用拦截器的afterCompletion方法,从preHandle执行到的最后一个开始倒序执行到第一个
      // 比如一共5个拦截器,
      // 如果正常执行preHandle方法且全部都返回true,那么就从第5个开始倒序执行afterCompletion到第一个拦截器
      // 如果执行到某个preHandle方法发生异常,那么就从第报错的那个拦截器之前的一个开始倒序执行afterCompletion到第一个拦截器
      triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
   }
   catch (Throwable err) {
      triggerAfterCompletion(processedRequest, response, mappedHandler,
            new NestedServletException("Handler processing failed", err));
   }
   finally {
     // ...
   }
}

AbstractHandlerMethodAdapter

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

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

RequestMappingHandlerAdapter

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

   ModelAndView mav;
   checkRequest(request);

   if (this.synchronizeOnSession) {
      HttpSession session = request.getSession(false);
      if (session != null) {
         Object mutex = WebUtils.getSessionMutex(session);
         synchronized (mutex) {
            mav = invokeHandlerMethod(request, response, handlerMethod);
         }
      }
      else {
         mav = invokeHandlerMethod(request, response, handlerMethod);
      }
   }
   else {
      // 开始反射调用controller中的方法
      // controller对象和方法都组合在HandlerMethod类中 
      mav = invokeHandlerMethod(request, response, handlerMethod);
   }

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

   return mav;
}
protected 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);

      // 根据匹配到的handlerMethod,将其属性组合到ServletInvocableHandlerMethod中。
      ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
       
      // ...
      ModelAndViewContainer mavContainer = new ModelAndViewContainer();
      // ...
       
      // 开始反射调用controller中的方法,方法调用的结果放在mavContainer中
      invocableMethod.invokeAndHandle(webRequest, mavContainer);
      if (asyncManager.isConcurrentHandlingStarted()) {
         return null;
      }
	  
      // 处理方法调用的结果
      return getModelAndView(mavContainer, modelFactory, webRequest);
   }
   finally {
      webRequest.requestCompleted();
   }
}

ServletInvocableHandlerMethod

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
      Object... providedArgs) throws Exception {
   // 开始调用controller中的方法	
   Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
 
   // ... 
    
   try {
      // 将放回结果包装成ModelAndView到mavContainer中 
      this.returnValueHandlers.handleReturnValue(
            returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
   }
   catch (Exception ex) {
      if (logger.isTraceEnabled()) {
         logger.trace(formatErrorForReturnValue(returnValue), ex);
      }
      throw ex;
   }
}

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));
   }
   // 使用method.invoke反射调用controller的方法 
   return doInvoke(args);
}

protected Object doInvoke(Object... args) throws Exception {
		ReflectionUtils.makeAccessible(getBridgedMethod());
		try {
			return getBridgedMethod().invoke(getBean(), args);
		}
		catch (IllegalArgumentException ex) {
		    // ...
		}
		catch (InvocationTargetException ex) {
			// ...
		}
}


2、分析下应用启动过程中处理url和controller中method的映射

RequestMappingHandlerMapping

public void afterPropertiesSet() {
   this.config = new RequestMappingInfo.BuilderConfiguration();
   this.config.setUrlPathHelper(getUrlPathHelper());
   this.config.setPathMatcher(getPathMatcher());
   this.config.setSuffixPatternMatch(useSuffixPatternMatch());
   this.config.setTrailingSlashMatch(useTrailingSlashMatch());
   this.config.setRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch());
   this.config.setContentNegotiationManager(getContentNegotiationManager());

   super.afterPropertiesSet();
}

AbstractHandlerMethodMapping

private final MappingRegistry mappingRegistry = new MappingRegistry();

public void afterPropertiesSet() {
   initHandlerMethods();
}

protected void initHandlerMethods() {
    // getCandidateBeanNames从spring中获取所有的beanNames
	for (String beanName : getCandidateBeanNames()) {
		if (!beanName.startsWith("scopedTarget.")) {
			processCandidateBean(beanName);
		}
	}
	handlerMethodsInitialized(getHandlerMethods());
}

protected void processCandidateBean(String beanName) {
	Class<?> beanType = null;
	try {
		beanType = obtainApplicationContext().getType(beanName);
	}
	catch (Throwable ex) {
		// ...
	}
    // isHandler方法,beanType对应的类具有Controller或者RequestMapping注解则返回true	
	if (beanType != null && isHandler(beanType)) {
		detectHandlerMethods(beanName);
	}
}

protected void detectHandlerMethods(Object handler) {
   Class<?> handlerType = (handler instanceof String ?
         obtainApplicationContext().getType((String) handler) : handler.getClass());

   if (handlerType != null) {
      // 获取真实的我们自己写的类,非代理类 
      Class<?> userType = ClassUtils.getUserClass(handlerType);
      // 遍历Controller类的方法,获取method和RequestMappingInfo的map集合 
      Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
            (MethodIntrospector.MetadataLookup<T>) method -> {
               try {
                  // 为方法生成RequestMappingInfo(组合方法的RequestMapping注解的属性)
                  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));
      }
      // 开始遍历上面的Map,将RequestMappingInfo和HandlerMethod(组合method和handler(我们的controller类))
      // 放入MappingRegistry的mappingLookup(一个Map)属性中
      methods.forEach((method, mapping) -> {
         Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
         registerHandlerMethod(handler, invocableMethod, mapping);
      });
   }
}

protected void registerHandlerMethod(Object handler, Method method, T mapping) {
	this.mappingRegistry.register(mapping, handler, method);
}

MappingRegistry

private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap<>();

public void register(T mapping, Object handler, Method method) {
   // Assert that the handler method is not a suspending one.
   if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
      throw new IllegalStateException("Unsupported suspending handler method detected: " + method);
   }
   this.readWriteLock.writeLock().lock();
   try {
      // 组合method和Controller对象,生成一个HandlerMethod对象,
      // 注意handler只是个Controller的beanName,后面获取handler的时候,会从spring中获取beanName对应的handler(也就是我们的controller)
      HandlerMethod handlerMethod = createHandlerMethod(handler, method);
      validateMethodMapping(handlerMethod, mapping);
      // 将handlerMappingInfo和handlerMethod放入map 
      this.mappingLookup.put(mapping, handlerMethod);

      // RequestMapping的value值可能有多个,记录下url和handlerMappingInfo的关系
      List<String> directUrls = getDirectUrls(mapping);
      for (String url : directUrls) {
         this.urlLookup.add(url, mapping);
      }

      String name = null;
      if (getNamingStrategy() != null) {
         name = getNamingStrategy().getName(handlerMethod, mapping);
         addMappingName(name, handlerMethod);
      }

      CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
      if (corsConfig != null) {
         this.corsLookup.put(handlerMethod, corsConfig);
      }

      this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
   }
   finally {
      this.readWriteLock.writeLock().unlock();
   }
}

3、分析下获取handler的过程

AbstractHandlerMapping

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   // 根据请求的路径获取对应的HandlerMethod
   Object handler = getHandlerInternal(request);
   if (handler == null) {
      handler = getDefaultHandler();
   }
   if (handler == null) {
      return null;
   }
    
   if (handler instanceof String) {
      String handlerName = (String) handler;
      handler = obtainApplicationContext().getBean(handlerName);
   }
   // 将Handler和HandlerInterceptor组合到HandlerExecutionChain中
   HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

   if (logger.isTraceEnabled()) {
      logger.trace("Mapped to " + handler);
   }
   else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
      logger.debug("Mapped to " + executionChain.getHandler());
   }

   if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
      CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
      CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
      config = (config != null ? config.combine(handlerConfig) : handlerConfig);
      executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
   }

   return executionChain;
}

AbstractHandlerMethodMapping

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
   String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
   request.setAttribute(LOOKUP_PATH, lookupPath);
   this.mappingRegistry.acquireReadLock();
   try {
      // 寻找最佳匹配的handlerMethod 
      HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
      // 从spring中获取handler(Controller)对应的对象,并重新生成一个HandlerMethod返回
      return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
   }
   finally {
      this.mappingRegistry.releaseReadLock();
   }
}

HandlerMethod

public HandlerMethod createWithResolvedBean() {
   Object handler = this.bean;
   if (this.bean instanceof String) {
      Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory");
      String beanName = (String) this.bean;
      // 从spring中获取handler(Controller)对应的对象 
      handler = this.beanFactory.getBean(beanName);
   }
   return new HandlerMethod(this, handler);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值