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