日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

SpringBoot自定义异常源码分析

發布時間:2023/11/27 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot自定义异常源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SpringBoot自定義異常源碼分析

?

在類上加ControllerAdvice注解,在方法上加ExceptionHandler注解,就可以在方法里處理相應的異常。

1.自定義異常處理類AdditionalExceptionHandler

掛@RestControllerAdvice注解:

------------------

2.自定義異常處理類GlobalExceptionHandler

=======================

初始調用鏈

main函數出發refreshContext

調用refresh

?進入context

?

AbstractApplicationContext調用beanFactory

getBean

?

org.springframework.beans.factory.support包下的一系列factory調用:

?SimpleInstantiationStrategy類的

instantiate方法觸發對WebMvcAutoConfiguration的反射

WebMvcAutoConfiguration類

configureHandlerExceptionResolvers方法

調用addDefaultHandlerExceptionResolvers(exceptionResolvers);

addDefaultHandlerExceptionResolvers類

調用exceptionHandlerResolver.afterPropertiesSet();

ExceptionHandlerExceptionResolver類的

afterPropertiesSet()調用initExceptionHandlerAdviceCache()

-----------------

異常核心處理類ExceptionHandlerExceptionResolver類

這個類掃描了所有標注有ExceptionHandler注解的方法,并將他們存入exceptionHandlerAdviceCache中

------------

initExceptionHandlerAdviceCache方法

先找到異常注解的bean

List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

對其循環

for (ControllerAdviceBean adviceBean : adviceBeans)

判斷是否有異常映射

if (resolver.hasExceptionMappings())

放到異常句柄緩存

this.exceptionHandlerAdviceCache.put(adviceBean, resolver);

-----------------------

ControllerAdviceBean類的findAnnotatedBeans方法找到@ControllerAdvice注解的bean

findAnnotatedBeans流式編程findAnnotationOnBean判斷是否是ControllerAdvice.class

?

------------------------

ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);

調用ExceptionHandlerMethodResolver,這里就是

遍歷自定義異常類AdditionalExceptionHandler (參考1)的方法method

-------------------

selectMethods判斷是否有ExceptionHandler注解

------

這個MethodIntrospector類的selectMethods很復雜

Select methods on the given target type based on the lookup of associated metadata.

查找給定類型的方法

>>>

selectMethods調用ReflectionUtils.doWithMethods

<<<回到selectMethods判斷是否橋接方法

Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {methodMap.put(specificMethod, result);
}

什么時候會生成橋接方法
那什么時候編譯器會生成橋接方法呢?可以查看JLS中的描述http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.4.5。

就是說一個子類在繼承(或實現)一個父類(或接口)的泛型方法時,在子類中明確指定了泛型類型,那么在編譯時編譯器會自動生成橋接方法

------------------------

最關鍵就是EXCEPTION_HANDLER_METHODS

EXCEPTION_HANDLER_METHODS判斷是否有ExceptionHandler注解,

回過來看AdditionalExceptionHandler自定義異常定義了有ExceptionHandler注解的方法

--------------------

ExceptionHandlerMethodResolver的addExceptionMapping的put操作:

=====================

hasExceptionMappings判斷方法:

mappedMethods定義:

?

看看mappedMethods的調用,直接點或者Ctrl+Alt+H都可以看到變量調用點:

--------------

?

this.exceptionHandlerAdviceCache.put(adviceBean, resolver);

?

如果覺得前面的分析比較繁瑣,這個寫的比較簡潔可以參考下

https://juejin.im/post/5cad5143f265da03b20413a6

==========================

【異常的觸發】

前面講了異常的注解初始化的時候掃描,現在我們故意觸發一段異常。

json數據格式異常觸發fastjson異常。這個異常被

DispatcherServlet的doDispatch捕獲

processDispatchResult結果處理

判斷是否是異常,是異常進行異常處理processHandlerException

遍歷handlerExceptionResolvers。

?

進入

protected final ModelAndView doResolveException

再進入doResolveHandlerMethodException

getExceptionHandlerMethod

異常判斷

異常類型判斷

resolveMethod調用resolveMethodByThrowable

異常命中以后

ServletInvocableHandlerMethod(advice.resolveBean(), method);

進入HandlerMethod

回到

doResolveHandlerMethodException

進入

exceptionHandlerMethod.invokeAndHandle

開始反射執行自定義的全局異常

bean就是之前定義的GlobalExceptionHandler

進入自定義的異常處理方法

封裝返回對象

一直返回多次回到

invokeAndHandle

返回ModelAndView()

返回

回到processRequest

經過一系列的FilterChain

回到tomcat的代碼做輸出了

總結

以上是生活随笔為你收集整理的SpringBoot自定义异常源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。