欧美1区2区3区激情无套,两个女人互添下身视频在线观看,久久av无码精品人妻系列,久久精品噜噜噜成人,末发育娇小性色xxxx

SpringBoot異常處理?用這兩個(gè)就夠啦!

在日常項(xiàng)目中,我們難免會(huì)遇到系統(tǒng)錯(cuò)誤的情況。如果對(duì)系統(tǒng)異常的情況不做處理,Springboot本身會(huì)默認(rèn)將錯(cuò)誤異常作為接口的請(qǐng)求返回。

?@GetMapping("/testNorError")
?public void testNorError() {
? ? ?try {
? ? ? ? ?throw new MyException(6000, "我的錯(cuò)誤");
? ?  }catch (Exception e){
? ? ? ? ?throw new MyException(5000, "我的包裝異常", e);
? ?  }
?}

從上圖可以看到,Springboot沒有對(duì)異常進(jìn)行處理的情況下,將錯(cuò)誤的堆棧直接當(dāng)做響應(yīng)數(shù)據(jù)返回了。這樣對(duì)用戶既不友好,又可能因?yàn)樾孤┫到y(tǒng)堆棧信息引發(fā)潛在的安全風(fēng)險(xiǎn)。因此,搭建一個(gè)完善的異常處理機(jī)制,對(duì)于維護(hù)系統(tǒng)健壯性是十分必要的。

通用異常處理

要快速的搭建異常處理機(jī)制,那么需要考慮如何對(duì)異常進(jìn)行捕獲并加以處理?最便捷的方法便是用 @ExceptionHandler注解實(shí)現(xiàn)。

? ? ?@ExceptionHandler(MyException.class)
? ? ?protected ResponseEntity<Object> handleException(Exception ex) {
? ? ? ? ?LOGGER.error("Failed to execute,handleException:{}", ex.getMessage(), ex);
? ? ? ? ?return new ResponseEntity<>(new ResultDTO().fail(ResultCodeEnum.ERROR_SERVER), HttpStatus.OK);
? ?  }

通過在Controller內(nèi)添加上述的異常處理代碼,Springboot就可以將相關(guān)的錯(cuò)誤信息轉(zhuǎn)義成系統(tǒng)的統(tǒng)一錯(cuò)誤處理,進(jìn)而避免堆棧外露。(這里的ResultDTO是系統(tǒng)內(nèi)自定義的JSON結(jié)構(gòu),可以根據(jù)自己的業(yè)務(wù)自行修改。)

然而,@ExceptionHandler本身存在一個(gè)弊端,就是他作用的范圍必須是Controller,也就意味著有多少個(gè)Controller,你的異常處理代碼便要重復(fù)寫多遍,這無(wú)疑是低效率的。為了減少重復(fù)的代碼冗余,@ControllerAdvance就進(jìn)入了我們的視野。

?@ControllerAdvice
?@Slf4j
?public class ExtGlobalExceptionHandler {
? ? ?
? ? ?@ExceptionHandler(Exception.class)
? ? ?protected ResponseEntity<Object> handleException(Exception ex) {
? ? ? ? ?LOGGER.error("Failed to execute,handleException:{}", ex.getMessage(), ex);
? ? ? ? ?return new ResponseEntity<>(new ResultDTO().fail(ResultCodeEnum.ERROR_SERVER), HttpStatus.OK);
? ?  }
?}

簡(jiǎn)單來(lái)說(shuō),@ControllerAdvance是一個(gè)全局處理的注解,其中的代碼會(huì)對(duì)所有的Controller生效,通常會(huì)搭配@ExceptionHandler處理異常,由此以來(lái)就可以實(shí)現(xiàn)只編寫一次異常處理方法就可以處理全局異常的情況。

至于@ControllerAdvance和@ExceptionHandler是如何實(shí)現(xiàn)這個(gè)神奇的功能的,限于篇幅原因,后續(xù)會(huì)考慮單獨(dú)出一篇文章詳細(xì)介紹。(其實(shí)根據(jù)名字,不難推斷ControllerAdvance就是一種針對(duì)于Controller對(duì)象的動(dòng)態(tài)代理罷了。)

個(gè)性化異常處理

用了@ControllerAdvance和ExceptionHandler,幾乎可以解決80%的項(xiàng)目面臨的報(bào)錯(cuò)處理問題。然而,思考一下。如果一個(gè)項(xiàng)目中出現(xiàn)了多組人同時(shí)維護(hù)、迭代一個(gè)系統(tǒng)的時(shí)候(降本增效嘛,懂的都懂),每組人要關(guān)注的報(bào)錯(cuò)自然會(huì)不一樣。如A組人只關(guān)注報(bào)錯(cuò)A,B組人員只關(guān)注報(bào)錯(cuò)B,那么這種通用的異常解決方案是無(wú)法區(qū)分開的。

針對(duì)于這種情況,就不得不請(qǐng)出另外一位大佬了,他就是:AOP,針對(duì)于動(dòng)態(tài)代理有很多的實(shí)現(xiàn)方式和框架,這里我們直接默認(rèn)采用SpringBoot的自帶AOP框架:

?<dependency>
? ? ?<groupId>org.springframework.boot</groupId>
? ? ?<artifactId>spring-boot-starter-aop</artifactId>
? ? ?<version>2.1.11.RELEASE</version>
?</dependency>

不管選擇的AOP實(shí)現(xiàn)框架是什么,要采用AOP編碼都少不了以下兩個(gè)步驟:

1、定義切點(diǎn)和執(zhí)行時(shí)機(jī)(哪些地方要做增強(qiáng))

2、定義通知(要怎么增強(qiáng))

定義切點(diǎn)和執(zhí)行時(shí)機(jī)

對(duì)于Springboot自帶的AOP框架,其執(zhí)行時(shí)機(jī)共有以下五個(gè):

@After

后置增強(qiáng)

目標(biāo)方法執(zhí)行之后調(diào)用增強(qiáng)方法

@Before

前置增強(qiáng)

目標(biāo)方法執(zhí)行之前先調(diào)用增強(qiáng)方法

@AfterReturning

返回增強(qiáng)

目標(biāo)方法執(zhí)行return之后返回結(jié)果之前調(diào)用增強(qiáng)方法,如果出異常則不執(zhí)行

@AfterThrowing

異常增強(qiáng)

目標(biāo)方法執(zhí)行產(chǎn)生異常調(diào)用增強(qiáng)方法,需注意的是,處理后異常依舊會(huì)往上拋出,不會(huì)被catch。

@Around

環(huán)繞增強(qiáng)

環(huán)繞增強(qiáng)包含前面四種增強(qiáng),通過一定的try-catch處理,環(huán)繞類型可以替代上述的任意一種增強(qiáng)。

了解了SpringBoot的動(dòng)態(tài)代理的執(zhí)行時(shí)機(jī)之后,我們還需要知道其定義切點(diǎn)的方式。框架定義切點(diǎn)的方式主要有兩個(gè):

  • 切點(diǎn)表達(dá)式
  • 注解

注釋

我們首先介紹注釋的正確打開方式。要通過注解來(lái)實(shí)現(xiàn)自己的AOP,那么首先需要定義一個(gè)新的注解。這里我簡(jiǎn)單定義了一個(gè)注解:

?@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
?@Retention(RetentionPolicy.RUNTIME)
?@Documented
?public @interface MyAnnotation {
?    
? ? ?String SERVER_NAME() default "";
??
? ? ?String action() default "";
?}

在定義了注解以后,將注解定義為方法的入?yún)?,并通過@annotation()標(biāo)注出注解的變量名稱,由此就可以實(shí)現(xiàn)注解AOP的功能。

?//處理注解的地方
?@Around(value = "@annotation(name)")
?public <T> T test(ProceedingJoinPoint point, MyAnnotation name) throws Throwable {
? ? ?String serverName = name.SERVER_NAME();
? ? ?//處理異常
? ? ?return handlerRpcException(point, serverName);
?}
??
?//具體代碼執(zhí)行處
?@MyAnnotation(SERVER_NAME = "下游系統(tǒng)", action = "操作處理")
?public <T> T testFunction() {
? ? ?return (T) new ResultDTO<>().success(Boolean.TRUE);
?}

切點(diǎn)表達(dá)式

Springboot的AOP中,還提供了一種十分強(qiáng)大的實(shí)現(xiàn)動(dòng)態(tài)代理切點(diǎn)標(biāo)注的方式,即切點(diǎn)表達(dá)式,其基本模式如下所示:

?execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

注意到modifiers-pattern?、declaring-type-pattern?、throws-pattern?等攜帶問號(hào)的參數(shù)都是非必填的。緊接著我們來(lái)逐一介紹上述參數(shù)的含義:

  • modifiers-pattern? :修飾符匹配,主要表示的是切點(diǎn)是public/private/protected/default的哪一種。
  • ret-type-pattern:顧名思義,指的是返回值的類型,常見如:void/Boolean/String等
  • declaring-type-pattern? :這個(gè)指的是被增強(qiáng)的方法、屬性的類路徑,如com.example.demo.service.aop.MyAspect等
  • name-pattern(param-pattern) :這個(gè)是相對(duì)關(guān)鍵的參數(shù),指的是被增強(qiáng)的方法名稱以及其對(duì)應(yīng)的參數(shù)類型。
  • throws-pattern:throw-pattern見詞知意,可以知道它是指的方法所拋出的異常類型。

除了了解了上述的表達(dá)式的基本匹配含義以外,還有幾個(gè)特殊的符號(hào)通配指的提一下:

***** :匹配任何數(shù)量字符 .. :匹配任何數(shù)量字符的重復(fù),如在類型模式中匹配任何數(shù)量子包;而在方法參數(shù)模式中匹配任何數(shù)量參數(shù)(0個(gè)或者多個(gè)參數(shù)) + :匹配指定類型及其子類型;僅能作為后綴放在類型模式后邊

也許上面的代碼和介紹讓你一臉懵逼,沒關(guān)系,可以簡(jiǎn)單看下下面兩個(gè)表達(dá)式的含義,你就大致明白他們的含義了:

?// 1、代表【返回值任意】且前綴為【com.example.demo.rpc】的【任意類下】【任意名稱】的【所有參數(shù)】方法
?execution(* com.example.demo.rpc.*.*(..))
??
?// 2、代表【返回值為Boolean】且位于【com.example.demo.rpc及其子包下】的【任意名稱】的【以String為最后一個(gè)入?yún)?shù)】的方法
?execution(Boolean com.example.demo.rpc..*(.., String))

借助于切面表達(dá)式,我們可以很自由靈活地定義出我們的切點(diǎn),從而通過AOP實(shí)現(xiàn)我們對(duì)于異常的處理

@Pointcut("execution(Boolean com.example.demo.rpc..*(.., String)) || execution(另外一個(gè)表達(dá)式)")
	private void PointCutOfAnno() {
}

@Around(value = "PointCutOfAnno()")
public <T> T testForAOP(ProceedingJoinPoint point) throws Throwable {
    //處理對(duì)應(yīng)的異常
    return handlerRpcException(point, serverName);
}

總結(jié)

本文介紹了兩種Springboot下針對(duì)于異常處理的編寫方法:

一、借助于@ControllerAdvance和@ExceptionHandler實(shí)現(xiàn)的通用異常處理方法

二、借助于AOP實(shí)現(xiàn)的個(gè)性化異常處理機(jī)制。

兩者其實(shí)本質(zhì)上的實(shí)現(xiàn)思路都是一樣的,通過對(duì)執(zhí)行代碼做動(dòng)態(tài)代理,從而將錯(cuò)誤包裝起來(lái),達(dá)到異常不外漏的效果。在實(shí)際業(yè)務(wù)場(chǎng)景中,方法一幾乎可以涵蓋80%的異常處理場(chǎng)景。方案二則主要針對(duì)一個(gè)系統(tǒng)中需要做個(gè)性化處理的情況,可以根據(jù)具體的業(yè)務(wù)需要進(jìn)行選擇。

全部評(píng)論
感恩的心 感謝有佬跪求多更
點(diǎn)贊 回復(fù) 分享
發(fā)布于 2023-03-14 11:33 上海
omg終于知道咋處理了
點(diǎn)贊 回復(fù) 分享
發(fā)布于 2023-03-14 11:30 廣東

相關(guān)推薦

高斯林的信徒:武大簡(jiǎn)歷掛?我勒個(gè)騷崗
點(diǎn)贊 評(píng)論 收藏
分享
評(píng)論
點(diǎn)贊
1
分享

創(chuàng)作者周榜

更多
??途W(wǎng)
??推髽I(yè)服務(wù)