最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中@ExceptionHandler注解的工作原理詳解

 更新時(shí)間:2024年01月25日 09:44:18   作者:安迪源文  
這篇文章主要介紹了Spring中@ExceptionHandler注解的工作原理詳解,Spring Web注解@ExceptionHandler可以用來(lái)指定處理某類異常的控制器方法,從而在這些異常發(fā)生時(shí),會(huì)有相應(yīng)的控制器方法來(lái)處理此類異常,需要的朋友可以參考下

@ExceptionHandler注解工作原理

我們知道,Spring Web注解@ExceptionHandler可以用來(lái)指定處理某類異常的控制器方法,從而在這些異常發(fā)生時(shí),會(huì)有相應(yīng)的控制器方法來(lái)處理此類異常,其定義方式如下 :

    /**
     * 此方法定義一個(gè)異常處理器,僅僅處理異常 DemoException , 它使用一個(gè)視圖對(duì)象 
     * DemoExceptionHandlerView 來(lái)處理異常 
     * @param e
     * @return
     */
    @ExceptionHandler(DemoException.class)
    public View handleDemoException(DemoException e) {
        return new DemoExceptionHandlerView(e);
    }

另外,通過(guò)@ExceptionHandler定義異常處理控制器方法,又可以分為兩類 :

  1. 定義在某個(gè)控制類內(nèi),這種情況下,所定義的異常處理控制器方法僅僅覆蓋當(dāng)前控制器類內(nèi)各個(gè)方法所發(fā)生的這類異常
  2. 結(jié)合@ControllerAdvice使用,定義在@ControllerAdvice注解的類內(nèi),這種情況下,所定義的異常處理控制器方法可用于@ControllerAdvice注解覆蓋的所有控制器類方法內(nèi)所發(fā)生的這類異常

那么,在這種現(xiàn)象背后,Spring MVC又是如何實(shí)現(xiàn)的呢 ? 實(shí)際上,這主要是 ExceptionHandlerExceptionResolver在起作用 :

首先,ExceptionHandlerExceptionResolver是Spring MVC缺省被啟用的一個(gè)HandlerExceptionResolver,它會(huì)被作為一個(gè)組合模式HandlerExceptionResolver bean中的一個(gè)元素進(jìn)入到bean容器中。

ExceptionHandlerExceptionResolver實(shí)現(xiàn)了接口InitializingBean,所以它在實(shí)例化時(shí)會(huì)被初始化。該過(guò)程中,它就會(huì)搜集所有的@ControllerAdvice注解類中使用@ExceptionHandler定義的異常處理控制器方法以供隨后工作時(shí)使用。

接下來(lái),DispatcherServlet初始化時(shí),會(huì)搜集所有HandlerExceptionResolver bean記錄到自己的策略組件屬性List<HandlerExceptionResolver> handlerExceptionResolvers。

然后,處理某個(gè)請(qǐng)求時(shí)某個(gè)異常發(fā)生了。DispatcherServlet會(huì)遍歷handlerExceptionResolvers中每個(gè)HandlerExceptionResolver對(duì)象試圖對(duì)該異常進(jìn)行處理。

    // DispatcherServlet 代碼片段,
    // 在 HandlerAdaptor 執(zhí)行 Handler 之后調(diào)用,
    // 如果之前的邏輯有異常,則 exception 不為 null,
    // 如果之前的邏輯執(zhí)行正常, 則 exception 為 null
	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {
		boolean errorView = false;
		if (exception != null) {
           // 請(qǐng)求處理出現(xiàn)了異常 
			if (exception instanceof ModelAndViewDefiningException) {
				logger.debug("ModelAndViewDefiningException encountered", exception);
				mv = ((ModelAndViewDefiningException) exception).getModelAndView();
			}
			else {
				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
              // 這里視圖處理該異常:
              // 1. 內(nèi)部將其完全處理
              // 2. 或者返回一個(gè)用于渲染錯(cuò)誤的數(shù)據(jù)模型和視圖
				mv = processHandlerException(request, response, handler, exception);
				errorView = (mv != null);
			}
		}
        // ... 省略其他代碼
    }        
	@Nullable
	protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
			@Nullable Object handler, Exception ex) throws Exception {
		// Success and error responses may use different content types
		request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
		// Check registered HandlerExceptionResolvers...
		ModelAndView exMv = null;
		if (this.handlerExceptionResolvers != null) {
          // 遍歷`handlerExceptionResolvers`中每個(gè)`HandlerExceptionResolver`對(duì)象
          // 試圖對(duì)異常 ex 進(jìn)行處理
			for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
				exMv = resolver.resolveException(request, response, handler, ex);
				if (exMv != null) {
					break;
				}
			}
		}
		if (exMv != null) {
			// ...
			return exMv;
		}
		throw ex;
	}    

這里,輪到ExceptionHandlerExceptionResolver處理異常時(shí),#resolveException最終會(huì)調(diào)用ExceptionHandlerExceptionResolver#doResolveHandlerMethodException。該處理過(guò)程主要步驟如下 :

找到能處理該異常的控制器方法 – ExceptionHandlerExceptionResolver#getExceptionHandlerMethod; 先從發(fā)生異常的控制器方法所在類查找是否存在使用注解@ExceptionHandler并能處理該異常的方法;如果找不到,從所有@ControllerAdvice注解類中查找使用注解@ExceptionHandler并能處理該異常的方法; 執(zhí)行處理該異常的控制器方法處理該異常;

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

相關(guān)文章

  • 在java中使用dom解析xml的示例分析

    在java中使用dom解析xml的示例分析

    本篇文章介紹了,在java中使用dom解析xml的示例分析。需要的朋友參考下
    2013-05-05
  • Hibernate組件映射代碼詳解

    Hibernate組件映射代碼詳解

    這篇文章主要介紹了Hibernate組件映射代碼詳解,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • Spring Boot集成Sorl搜索客戶端的實(shí)現(xiàn)代碼

    Spring Boot集成Sorl搜索客戶端的實(shí)現(xiàn)代碼

    本篇文章主要介紹了Spring Boot集成Sorl搜索客戶端的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • 使用MDC實(shí)現(xiàn)日志鏈路跟蹤

    使用MDC實(shí)現(xiàn)日志鏈路跟蹤

    這篇文章主要介紹了使用MDC實(shí)現(xiàn)日志鏈路跟蹤,在微服務(wù)環(huán)境中,我們經(jīng)常使用Skywalking、CAT等去實(shí)現(xiàn)整體請(qǐng)求鏈路的追蹤,但是這個(gè)整體運(yùn)維成本高,架構(gòu)復(fù)雜,我們來(lái)使用MDC通過(guò)Log來(lái)實(shí)現(xiàn)一個(gè)輕量級(jí)的會(huì)話事務(wù)跟蹤功能,下面就來(lái)看看具體的過(guò)程吧,需要的朋友可以參考一下
    2022-01-01
  • mybatis-plus 返回部分字段的解決方式

    mybatis-plus 返回部分字段的解決方式

    這篇文章主要介紹了mybatis-plus 返回部分字段的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • java微信開(kāi)發(fā)API第三步 微信獲取以及保存接口調(diào)用憑證

    java微信開(kāi)發(fā)API第三步 微信獲取以及保存接口調(diào)用憑證

    這篇文章主要為大家詳細(xì)介紹了java微信開(kāi)發(fā)API第二步,微信獲取以及保存接口調(diào)用憑證,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Maven編譯Fatal?error?compiling:無(wú)效的目標(biāo)發(fā)行版:11問(wèn)題及解決

    Maven編譯Fatal?error?compiling:無(wú)效的目標(biāo)發(fā)行版:11問(wèn)題及解決

    在Java11中編譯Springboot工程時(shí)遇到問(wèn)題,解決方法是在pom.xml文件中指定Maven的Java編譯器版本,可以使用MavenJava編譯器屬性或插件,在Java9及以后的版本中,也要使用插件并設(shè)置release屬性
    2024-12-12
  • SpringBoot實(shí)現(xiàn)PDF轉(zhuǎn)圖片的代碼示例

    SpringBoot實(shí)現(xiàn)PDF轉(zhuǎn)圖片的代碼示例

    在本文中,我們使用SpringBoot演示了如何將PDF文件轉(zhuǎn)換為一張或多張圖片,這些示例演示了如何使用Java編程語(yǔ)言與其他開(kāi)源技術(shù)集成,以實(shí)現(xiàn)各種文件格式之間的轉(zhuǎn)換,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-08-08
  • 詳細(xì)總結(jié)Java堆棧內(nèi)存、堆外內(nèi)存、零拷貝淺析與代碼實(shí)現(xiàn)

    詳細(xì)總結(jié)Java堆棧內(nèi)存、堆外內(nèi)存、零拷貝淺析與代碼實(shí)現(xiàn)

    零拷貝,這是個(gè)耳熟能詳?shù)拿~,是開(kāi)發(fā)崗面試中經(jīng)常提及的問(wèn)題.最近在回顧Netty的基礎(chǔ)原理,還是把NIO中關(guān)于堆外內(nèi)存的知識(shí)點(diǎn)過(guò)了一遍,這里就針對(duì)堆棧內(nèi)存 堆外內(nèi)存和零拷貝這幾個(gè)概念以及相關(guān)知識(shí)做一下記錄,需要的朋友可以參考下
    2021-05-05
  • 關(guān)于Mybatis中SQL節(jié)點(diǎn)的深入解析

    關(guān)于Mybatis中SQL節(jié)點(diǎn)的深入解析

    這篇文章主要給大家介紹了關(guān)于Mybatis中SQL節(jié)點(diǎn)的深入解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03

最新評(píng)論

永福县| 朝阳县| 锡林浩特市| 射洪县| 哈密市| 合江县| 房山区| 兴文县| 武强县| 堆龙德庆县| 印江| 武义县| 黑山县| 永福县| 湛江市| 农安县| 铁岭县| 贡嘎县| 长治市| 乐清市| 兰坪| 承德市| 漳平市| 会宁县| 金溪县| 长乐市| 玉树县| 宁陵县| 忻城县| 涿鹿县| 石泉县| 积石山| 青浦区| 汕尾市| 鄢陵县| 宜兴市| 榕江县| 河西区| 夏邑县| 庆云县| 金乡县|