阿里四面之Spring Exception的原理解析
錯(cuò)誤場(chǎng)景
驗(yàn)證請(qǐng)求的Token合法性的Filter。Token校驗(yàn)失敗時(shí),直接拋?zhàn)远x異常,移交給Spring處理:
測(cè)試HTTP請(qǐng)求:
日志輸出如下:說(shuō)明IllegalRequestExceptionHandler未生效。
why?這就需要精通Spring異常處理流程了。
解析
當(dāng)所有Filter被執(zhí)行完畢,Spring才會(huì)處理Servlet相關(guān),而DispatcherServlet才是整個(gè)Servlet處理核心,它是前端控制器設(shè)計(jì)模式,提供 Spring Web MVC 的集中訪問(wèn)點(diǎn)并負(fù)責(zé)職責(zé)的分派。
在這,Spring處理了請(qǐng)求和處理器的對(duì)應(yīng)關(guān)系及統(tǒng)一異常處理。
Filter內(nèi)異常無(wú)法被統(tǒng)一處理,就是因?yàn)楫惓L幚戆l(fā)生在 DispatcherServlet#doDispatch()
但此時(shí),過(guò)濾器已全部執(zhí)行完。
Spring異常統(tǒng)一處理 ControllerAdvice如何被Spring加載并對(duì)外暴露? WebMvcConfigurationSupport#handlerExceptionResolver()
實(shí)例化并注冊(cè)一個(gè)ExceptionHandlerExceptionResolver 的實(shí)例
最終按下圖調(diào)用棧,Spring 實(shí)例化了ExceptionHandlerExceptionResolver類。
ExceptionHandlerExceptionResolver實(shí)現(xiàn)了InitializingBean
重寫 afterPropertiesSet()
initExceptionHandlerAdviceCache
完成所有 ControllerAdvice 中的ExceptionHandler 初始化:查找所有 @ControllerAdvice 注解的 Bean,把它們放入exceptionHandlerAdviceCache。這里即指自定義的IllegalRequestExceptionHandler
所有被 @ControllerAdvice 注解的異常處理器,都會(huì)在 ExceptionHandlerExceptionResolver 實(shí)例化時(shí)自動(dòng)掃描并裝載在其exceptionHandlerAdviceCache。
initHandlerExceptionResolvers
當(dāng)?shù)谝淮握?qǐng)求發(fā)生時(shí),DispatcherServlet#initHandlerExceptionResolvers() 將獲取所有注冊(cè)到 Spring 的 HandlerExceptionResolver 實(shí)例(ExceptionHandlerExceptionResolver正是),存到handlerExceptionResolvers
ControllerAdvice如何被Spring消費(fèi)并處理異常? DispatcherServlet doDispatch()
執(zhí)行用戶請(qǐng)求時(shí),當(dāng)查找、執(zhí)行請(qǐng)求對(duì)應(yīng)的 handler 過(guò)程中異常時(shí):
會(huì)把異常值賦給 dispatchException再移交 processDispatchResult() processDispatchResult
當(dāng)Exception非空時(shí),繼續(xù)移交
processHandlerException
從 handlerExceptionResolvers 獲取有效的異常解析器以解析異常。
這里的 handlerExceptionResolvers 一定包含聲明的IllegalRequestExceptionHandler#IllegalRequestException 的異常處理器的 ExceptionHandlerExceptionResolver 包裝類。
修正
為利用到 Spring MVC 的異常處理機(jī)制,改造Filter:
手動(dòng)捕獲異常將異常通過(guò) HandlerExceptionResolver 進(jìn)行解析處理
據(jù)此,修改 PermissionFilter,注入 HandlerExceptionResolver:
然后,在 doFilter 捕獲異常并移交 HandlerExceptionResolver:
現(xiàn)在再用錯(cuò)誤 Token 請(qǐng)求,日志輸出如下:
響應(yīng)體:
到此這篇關(guān)于阿里四面之Spring Exception的原理解析的文章就介紹到這了,更多相關(guān)Spring Exception原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot異常: nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext解決方案
- 解決SpringBoot ClassPathResource的大坑(FileNotFoundException)
- 關(guān)于springcloud報(bào)錯(cuò)報(bào)UnsatisfiedDependencyException的問(wèn)題
- spring5 SAXParseException:cvc-elt.1: 找不到元素“beans 的聲明詳解
- 深入學(xué)習(xí)Spring Boot排查 @Transactional 引起的 NullPointerException問(wèn)題
相關(guān)文章
Java時(shí)間類庫(kù)Timer的使用方法與實(shí)例詳解
這篇文章主要介紹了Jave時(shí)間類庫(kù)Timer的使用方法與實(shí)例詳解,需要的朋友可以參考下2020-02-02Java?Spring?Boot請(qǐng)求方式與請(qǐng)求映射過(guò)程分析
這篇文章主要介紹了Java?Spring?Boot請(qǐng)求方式與請(qǐng)求映射過(guò)程分析,Spring?Boot支持Rest風(fēng)格:使用HTTP請(qǐng)求方式的動(dòng)詞來(lái)表示對(duì)資源的操作2022-06-06Windows下安裝ElasticSearch的方法(圖文)
這篇文章主要介紹了Windows下安裝ElasticSearch的方法(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Java8新特性之再見(jiàn)Permgen_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之再見(jiàn)Permgen的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-06-06SpringBoot定時(shí)任務(wù)實(shí)現(xiàn)數(shù)據(jù)同步的方法
業(yè)務(wù)需求是,通過(guò)中臺(tái)調(diào)用api接口獲得,設(shè)備數(shù)據(jù),要求現(xiàn)實(shí)設(shè)備數(shù)據(jù)的同步,這篇文章主要介紹了SpringBoot定時(shí)任務(wù)實(shí)現(xiàn)數(shù)據(jù)同步的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08