请求处理过程2-获取RequestMappingHandlerAdapter

获取到RequestMappingHandler处理器映射器后,再获取RequestMappingHandlerAdapter处理器适配器。完成controller方法的执行。
这个是通过RequestMappingHandlerAdapter类型的类完成的。

在这里插入图片描述

1.获取RequestMappingHandlerAdapter

在这里插入图片描述

	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    
    
		if (this.handlerAdapters != null) {
    
    
			for (HandlerAdapter adapter : this.handlerAdapters) {
    
    
				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");
	}

有4个,初始化和handlerMapper相同。在第一次请求是调用方法加载。
在这里插入图片描述
继续调用
在这里插入图片描述
会发现直接返回true。然后就获取到了这个RequestMappingHandlerAdapter。

2.执行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) {
    
    
					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;
	}

3.invokeHandlerMethod方法

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

		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
    
    
			//获取该方法的所有使用@InitBinder注解修饰的方法
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
		
        	//获取该方法的所有使用@ModelAttribute注解修饰的方法 包装成ModelFactory(包含类作用范围的和全局作用范围的)
			ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

        	//上面获取@InitBinder/@ModelAttribute注解修饰的方法雷同,都是先接卸handlerMethod对应的类
        	//中类范围的注解修饰的方法(解析完成后放入对应的缓存),接着获取@ControllerAdvice修饰的全局范围的使用如上注解修饰的方法
        	//将对应的方法包装成InvocableHandlerMethod用于后面的执行,并将其包装成WebDataBinderFactory/ModelFactory对象。
 
	        //两者的区别在于ModelFactory中不仅仅包含@ModelAttribute注解修饰的方法还包含@SessionAttribute注解修饰的model处理
        	//同时也将上面解析出来的WebDataBinderFactory存放到modelFactory中。
 
        	//将HandlerMethod方法包装成ServletInvocableHandlerMethod(该对象是InvocableHandlerMethod子类)
        	//设置相关的组件 比如设置参数解析组件argumentResolvers和返回结果处理组件returnValueHandlers
        	//绑定组件binderFactory和parameterNameDiscoverer
			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();
			
        	//对于重定向相关的参数保存需要依赖flashMap对象,如果一个请求是重定向请求 则input_flash_map保存重定向入参
        	//如果一个请求需要进行重定向 则参数会存放到output_flash_map中
			mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
			//调用@ModelAttribute注解修饰的方法将对应的属性存放到mavContainer 的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();
				LogFormatUtils.traceDebug(logger, traceOn -> {
    
    
					String formatted = LogFormatUtils.formatValue(result, !traceOn);
					return "Resume with async result [" + formatted + "]";
				});
				invocableMethod = invocableMethod.wrapConcurrentResult(result);
			}
			
        	//通过反射执行相关的handlerMethod 涉及参数解析,返回值的处理、
        	//invocableMethod已经包含了进行参数解析和返回值处理的组件对象
			invocableMethod.invokeAndHandle(webRequest, mavContainer);
			if (asyncManager.isConcurrentHandlingStarted()) {
    
    
				return null;
			}

        	//主要处理sessionAttribute 以及对model中的属性进行属性编辑器的转换处理@InitBinder
        	//对于view对象进行逻辑视图到物理视图的转换以及重定向参数的设置
			return getModelAndView(mavContainer, modelFactory, webRequest);
		}
		finally {
    
    
			webRequest.requestCompleted();
		}
	}

4.invokeAndHandle方法

	public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
    
    
		//反射调用controller方法 获取返回值
		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;
		}
	}

这个过程主要就是执行请求,包括具体的请求参数解析,返回值确定,视图解析,这三大部分。
还需要单独研究~~~~加油啊

参考链接1

猜你喜欢

转载自blog.csdn.net/weixin_46666822/article/details/124754965