欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springmvc九大組件之HandlerAdapter詳解

 更新時(shí)間:2023年11月18日 08:48:49   作者:morris131  
這篇文章主要介紹了springmvc九大組件之HandlerAdapter詳解,RequestMappingHandlerAdapter支持的handler的類型是HandlerMethod,而HandlerMethod是通過(guò)解析@RequestMapping注解獲得的,需要的朋友可以參考下

HandlerAdapter

HandlerAdapter處理器適配器用來(lái)執(zhí)行Controller中的目標(biāo)方法,由于上面有三種HandlerMapping,對(duì)應(yīng)這里三種HandlerAdapter:

  • RequestMappingHandlerAdapter:對(duì)應(yīng)RequestMappingHandlerMapping
  • HttpRequestHandlerAdapter:對(duì)應(yīng)SimpleUrlHandlerMapping
  • SimpleControllerHandlerAdapter:對(duì)應(yīng)BeanNameUrlHandlerMapping

當(dāng)然還有SimpleServletHandlerAdapter負(fù)責(zé)處理servlet請(qǐng)求,默認(rèn)不開(kāi)啟,用得少。

RequestMappingHandlerAdapter

根據(jù)handler獲得HandlerAdapter

RequestMappingHandlerAdapter支持的handler的類型是HandlerMethod,而HandlerMethod是通過(guò)解析@RequestMapping注解獲得的。

org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports

public final boolean supports(Object handler) {
	/**
		 * supportsInternal返回true
		 * @see RequestMappingHandlerAdapter#supportsInternal(org.springframework.web.method.HandlerMethod) 
		 */
	return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}

handler的執(zhí)行

RequestMappingHandlerAdapter通過(guò)反射執(zhí)行HandlerMethod。

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

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...
		// 調(diào)用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;
}

將HandlerMethod封裝為ServletInvocableHandlerMethod,ServletInvocableHandlerMethod負(fù)責(zé)真正的方法調(diào)用。

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 {
		WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
		ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

		// ServletInvocableHandlerMethod負(fù)責(zé)真正的方法調(diào)用
		ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
		if (this.argumentResolvers != null) {
			invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
		}
		if (this.returnValueHandlers != null) {
			invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
		}
		invocableMethod.setDataBinderFactory(binderFactory);
		invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

		ModelAndViewContainer mavContainer = new ModelAndViewContainer();
		mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
		// 處理@ModelAttribute注解
		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);
		}

		// 反射調(diào)用controller中的方法
		invocableMethod.invokeAndHandle(webRequest, mavContainer);
		if (asyncManager.isConcurrentHandlingStarted()) {
			return null;
		}

		return getModelAndView(mavContainer, modelFactory, webRequest);
	}
	finally {
		webRequest.requestCompleted();
	}
}

requestHandled為false表示后面還需要進(jìn)行視圖解析,requestHandled為true表示后面不需要進(jìn)行視圖解析,可以直接返回響應(yīng)。

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
								Object... providedArgs) throws Exception {

	// 反射調(diào)用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;
	}

	// requestHandled用來(lái)表示后面是否還需要進(jìn)行視圖解析
	mavContainer.setRequestHandled(false);
	Assert.state(this.returnValueHandlers != null, "No return value handlers");
	try {
		// 對(duì)返回結(jié)果進(jìn)行處理
		this.returnValueHandlers.handleReturnValue(
			returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
	}
	catch (Exception ex) {
		if (logger.isTraceEnabled()) {
			logger.trace(formatErrorForReturnValue(returnValue), ex);
		}
		throw ex;
	}
}

先進(jìn)行參數(shù)的解析,然后反射調(diào)用controller中的方法:

org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

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

		// 方法參數(shù)解析
		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
		if (logger.isTraceEnabled()) {
			logger.trace("Arguments: " + Arrays.toString(args));
		}
		// 反射調(diào)用controller中的方法
		return doInvoke(args);
	}

SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter主要負(fù)責(zé)執(zhí)行類型為Controller的handler,由于handler都實(shí)現(xiàn)了Controller接口,只需要調(diào)用Controller接口的handleRequest()方法即可。

package org.springframework.web.servlet.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;

public class SimpleControllerHandlerAdapter implements HandlerAdapter {

	@Override
	public boolean supports(Object handler) {
		return (handler instanceof Controller);
	}

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

		return ((Controller) handler).handleRequest(request, response);
	}
	... ...
}

HttpRequestHandlerAdapter

HttpRequestHandlerAdapter主要負(fù)責(zé)執(zhí)行類型為HttpRequestHandler的handler,由于handler都實(shí)現(xiàn)了HttpRequestHandler接口,只需要調(diào)用Controller接口的handleRequest()方法即可。

package org.springframework.web.servlet.mvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.lang.Nullable;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;

public class HttpRequestHandlerAdapter implements HandlerAdapter {

	@Override
	public boolean supports(Object handler) {
		return (handler instanceof HttpRequestHandler);
	}

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

		((HttpRequestHandler) handler).handleRequest(request, response);
		return null;
	}
	... ...
}

到此這篇關(guān)于springmvc九大組件之HandlerAdapter詳解的文章就介紹到這了,更多相關(guān)HandlerAdapter詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea項(xiàng)目實(shí)現(xiàn)移除和添加git

    idea項(xiàng)目實(shí)現(xiàn)移除和添加git

    本文指導(dǎo)讀者如何從官網(wǎng)下載并安裝Git,以及在IDEA中配置Git的詳細(xì)步驟,首先,用戶需訪問(wèn)Git官方網(wǎng)站下載適合自己操作系統(tǒng)的Git版本并完成安裝,接著,在IDEA中通過(guò)設(shè)置找到git.exe文件以配置Gi
    2024-10-10
  • Java設(shè)計(jì)模式之抽象工廠模式詳解

    Java設(shè)計(jì)模式之抽象工廠模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之抽象工廠模式詳解,抽象工廠是一種為訪問(wèn)類提供一個(gè)創(chuàng)建一組相關(guān)或相互依賴對(duì)象的接口,且訪問(wèn)類無(wú)須指定所要產(chǎn)品的具體類就能得到同族的、不同等級(jí)的產(chǎn)品的模式結(jié)構(gòu),需要的朋友可以參考下
    2023-09-09
  • java反射之獲取類的信息方法(推薦)

    java反射之獲取類的信息方法(推薦)

    下面小編就為大家?guī)?lái)一篇java反射之獲取類的信息方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Java Number類原理實(shí)例解析

    Java Number類原理實(shí)例解析

    這篇文章主要介紹了Java Number類原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Spring Security Remember me使用及原理詳解

    Spring Security Remember me使用及原理詳解

    這篇文章主要介紹了Spring Security Remember me使用及原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java實(shí)戰(zhàn)之圖書管理系統(tǒng)的實(shí)現(xiàn)

    Java實(shí)戰(zhàn)之圖書管理系統(tǒng)的實(shí)現(xiàn)

    這篇文章主要介紹了如何利用Java語(yǔ)言編寫一個(gè)圖書管理系統(tǒng),文中采用的技術(shù)有Springboot、SpringMVC、MyBatis、ThymeLeaf 等,需要的可以參考一下
    2022-03-03
  • Java中內(nèi)部類的概念與分類詳解

    Java中內(nèi)部類的概念與分類詳解

    一個(gè)類的定義放在另一個(gè)類的內(nèi)部,這個(gè)類就叫做內(nèi)部類,下面這篇文章主要給大家介紹了關(guān)于Java中內(nèi)部類的概念與分類的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-09-09
  • Java設(shè)計(jì)模式之建造者模式

    Java設(shè)計(jì)模式之建造者模式

    這篇文章介紹了Java設(shè)計(jì)模式之建造者模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Spring關(guān)于@Configuration配置處理流程

    Spring關(guān)于@Configuration配置處理流程

    這篇文章主要介紹了Spring關(guān)于@Configuration配置處理流程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • 基于Java語(yǔ)言的遞歸運(yùn)算例題詳解

    基于Java語(yǔ)言的遞歸運(yùn)算例題詳解

    一個(gè)方法在執(zhí)行過(guò)程中調(diào)用自身, 就稱為 "遞歸"。本文將通過(guò)幾個(gè)例題帶大家深入了解一下Java語(yǔ)言中的遞歸運(yùn)算,感興趣的可以了解一下
    2022-08-08

最新評(píng)論