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

SpringBoot一個請求的處理全過程分享

 更新時間:2024年12月14日 08:54:17   作者:騎個小蝸牛  
本文詳細介紹了SpringBoot請求處理的全過程,包括過濾器鏈、攔截器鏈、路徑映射、參數(shù)綁定、Controller方法執(zhí)行、返回值處理、異常解析和視圖解析渲染等步驟,同時,文中還列舉了請求處理過程中常見的問題及解決方案

平時只是在用SpringBoot框架,但并沒有詳細研究過請求執(zhí)行的一個具體過程,所以本文主要來梳理一下SpringBoot請求處理的全過程。

請求處理流程圖

容器包含關系圖

請求簡要流程圖

請求詳細流程圖

請求處理流程詳解

請求處理主要流程

  1. 過濾器鏈chain.doFilter之前的執(zhí)行(過濾器是在Server容器中的,如Tomcat);
  2. 攔截器鏈preHandle方法執(zhí)行;
  3. 路徑映射、參數(shù)綁定(參數(shù)解析、參數(shù)轉(zhuǎn)換、參數(shù)校驗);
  4. Controller的具體方法執(zhí)行;
  5. 返回值處理(含信息轉(zhuǎn)換);
  6. 攔截器鏈postHandle方法執(zhí)行;
  7. 異常解析器處理異常(@ControllerAdvice、自定義異常解析器都在這里執(zhí)行);
  8. 視圖解析渲染;
  9. 攔截器鏈afterCompletion方法執(zhí)行;
  10. 過濾器鏈chain.doFilter之后的執(zhí)行。

請求處理詳細流程

Tomcat線程接受到請求,經(jīng)過一系列調(diào)用后,調(diào)用到ApplicationFilterChain的doFilter方法。doFilter方法調(diào)用ApplicationFilterChain的internalDoFilter方法,依次執(zhí)行過濾器鏈的每個Filter的doFilter。

過濾器鏈的所有doFIlter執(zhí)行完畢, 控制權交回ApplicationFilterChain, 經(jīng)過一系列調(diào)用后,調(diào)用到DispatcherServlet的doDispatch方法。

doDispatch方法的主要流程:

  • DispatcherServlet的getHandler方法:得到處理執(zhí)行器鏈(包含處理器和攔截器鏈)。
  • DispatcherServlet的getHandlerAdapter方法:得到處理器適配器。
  • HandlerExecutionChain的applyPreHandle方法:執(zhí)行執(zhí)行器鏈中的所有攔截器方法preHandle。

AbstractHandlerMethodAdapter的handle方法:該方法主要包含路徑映射、參數(shù)bangd (參數(shù)解析、參數(shù)轉(zhuǎn)換、參數(shù)校驗)、調(diào)用具體控制器方法、返回值處理(含信息轉(zhuǎn)換)等操作。

handle方法的主要流程:

  • 調(diào)用RequestMappingHandlerAdapter的handleInternal方法
  • handleInternal方法又調(diào)用RequestMappingHandlerAdapter的invokeHandlerMethod方法

invokeHandlerMethod方法的主要流程:

  • 調(diào)用RequestMappingHandlerAdapter的createInvocableHandlerMethod方法:注冊參數(shù)解析器、返回值處理器、信息轉(zhuǎn)化器等到ServletInvocableHandlerMethod 對象實例中。
  • 調(diào)用ServletInvocableHandlerMethod的invokeAndHandle方法。

invokeAndHandle方法的主要流程:

  • 調(diào)用InvocableHandlerMethod的invokeForRequest方法
  • invokeForRequest方法又調(diào)用InvocableHandlerMethod的doInvoke方法

doInvoke方法的主要流程:

  • 調(diào)用InvocableHandlerMethod的getMethodArgumentValues方法:路徑映射、參數(shù)綁定(參數(shù)解析、參數(shù)轉(zhuǎn)換、參數(shù)校驗)。
  • 調(diào)用Method的invoke方法,內(nèi)部調(diào)用DelegatingMethodAccessorImpl的invoke方法,內(nèi)部調(diào)用InvocableHandlerMethod的doInvoke方法,內(nèi)部調(diào)用NativeMethodAccessorImpl的invoke方法,內(nèi)部調(diào)用NativeMethodAccessorImpl的invoke0方法,內(nèi)部調(diào)用具體Controller的具體方法,得到響應結(jié)果。
  • 調(diào)用HandlerMethodReturnValueHandlerComposite的handleReturnValue方法:返回值處理(含信息轉(zhuǎn)換)。
  • 調(diào)用HandlerExecutionChain的applyPostHandle方法:執(zhí)行執(zhí)行器鏈中的所有攔截方法postHandle。
  • 調(diào)用DispatcherServlet的processDispatchResult方法。

processDispatchResult方法的主要流程:

  • 調(diào)用DispatcherServlet的processHandlerException方法:異常處理(獲取合適的異常解析器處理異常信息,@ControllerAdvice全局異常處理和自定義異常解析器都是在這一步執(zhí)行的)。
  • 調(diào)用DispatcherServlet的render方法:視圖解析渲染。
  • 調(diào)用HandlerExecutionChain的triggerAfterCompletion方法:執(zhí)行執(zhí)行器鏈中的所有攔截方法afterCompletion。
  • 控制權交回ApplicationFilterChain , 繼續(xù)執(zhí)行過濾器鏈的所有doFIlter之后的代碼。

常見問題

全局異常處理失效

1.@ControllerAdvice作用范圍

攔截器的preHandle方法、postHandle方法拋出的異常在ControllerAdvice處理范圍內(nèi),但攔截器的afterCompletion方法拋出的異常不在處理范圍內(nèi)(攔截器的afterCompletion拋出的異常會被直接catch處理,不會往外拋出異常,只會打印錯誤日志)。

HandlerExecutionChain類源碼

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

過濾器拋出的異常不在ControllerAdvice處理范圍內(nèi)。要處理過濾器拋出的異常,可以自定義Filter并放在過濾鏈的最前面,catch處理異常。

2.多個@ControllerAdvice優(yōu)先級問題

  • 多個使用@ControllerAdvice 的Bean按執(zhí)行順序(通過Order注解設置執(zhí)行順序,值越小月優(yōu)先執(zhí)行)依次執(zhí)行
  • 當某個Bean的方法匹配上異常時,進行異常處理,直接返回,后續(xù)的方法和Bean不在執(zhí)行。

關于全局異常處理詳細講解可參考文章:[SpringBoot全局異常處理]

后續(xù)文章會繼續(xù)針對請求流程里面的一些主要功能作深入探討,如:過濾器攔截器、參數(shù)解析、參數(shù)轉(zhuǎn)換參數(shù)校驗、返回值處理、異常處理等方面

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SSM框架通過mybatis-generator自動生成代碼(推薦)

    SSM框架通過mybatis-generator自動生成代碼(推薦)

    這篇文章主要介紹了SSM框架通過mybatis-generator自動生成代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2017-11-11
  • Java解析DICOM圖之如何獲得16進制數(shù)據(jù)詳解

    Java解析DICOM圖之如何獲得16進制數(shù)據(jù)詳解

    DICOM就是醫(yī)學數(shù)字成像和通信,是醫(yī)學圖像和相關信息的國際標準(ISO 12052),下面這篇文章主要給大家介紹了關于Java解析DICOM圖之如何獲得16進制數(shù)據(jù)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2017-10-10
  • Java數(shù)據(jù)結(jié)構之KMP算法詳解以及代碼實現(xiàn)

    Java數(shù)據(jù)結(jié)構之KMP算法詳解以及代碼實現(xiàn)

    KMP算法是一種改進的字符串匹配算法,核心是利用之前的匹配失敗時留下的信息,選擇最長匹配長度直接滑動,從而減少匹配次數(shù)。本文主要介紹了KMP算法的原理與實現(xiàn),需要的可以參考一下
    2022-12-12
  • 淺談spring中用到的設計模式及應用場景

    淺談spring中用到的設計模式及應用場景

    下面小編就為大家?guī)硪黄獪\談spring中用到的設計模式及應用場景。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java基礎篇之對象數(shù)組練習

    Java基礎篇之對象數(shù)組練習

    對象數(shù)組就是數(shù)組里的每個元素都是類的對象,賦值時先定義對象,然后將對象直接賦給數(shù)組就行了,這篇文章主要給大家介紹了關于Java基礎篇之對象數(shù)組練習的相關資料,需要的朋友可以參考下
    2024-03-03
  • Springboot基于BCrypt非對稱加密字符串的實現(xiàn)

    Springboot基于BCrypt非對稱加密字符串的實現(xiàn)

    本文主要介紹了Springboot基于BCrypt非對稱加密字符串的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 關于Spring中的@Configuration中的proxyBeanMethods屬性

    關于Spring中的@Configuration中的proxyBeanMethods屬性

    這篇文章主要介紹了關于Spring中的@Configuration中的proxyBeanMethods屬性,需要的朋友可以參考下
    2023-07-07
  • Java設計模式之抽象工廠模式(Abstract?Factory)

    Java設計模式之抽象工廠模式(Abstract?Factory)

    這篇文章主要為大家詳細介紹了Java設計模式之抽象工廠模式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 詳解Spring如何解析占位符

    詳解Spring如何解析占位符

    Spring一直支持將屬性定義到外部的屬性的文件中,并使用占占位符的形式為使用"${}"包裝的屬性名稱,為了使用屬性占位符,我們必須配置一個PropertyPlaceholderConfigurer或PropertySourcesPlaceholderConfigurer實例,本文將介紹如何解析占位符
    2021-06-06
  • java復制文件和java移動文件的示例分享

    java復制文件和java移動文件的示例分享

    本文主要介紹了java將文件夾下面的所有的jar文件拷貝到指定的文件夾下面的方法,需要的朋友可以參考下
    2014-02-02

最新評論