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

Spring Boot異常處理try-catch應(yīng)該怎么使用?

 更新時(shí)間:2026年01月31日 09:02:47   作者:Qiuner  
這篇文章詳細(xì)介紹了Web系統(tǒng)中異常處理的重要性,以及SpringMVC的異常處理機(jī)制,解釋了異常在系統(tǒng)中的角色,討論了Java異常模型的關(guān)鍵認(rèn)知,包括Throwable體系結(jié)構(gòu)和異常傳播,強(qiáng)調(diào)了在Web系統(tǒng)中不應(yīng)該到處使用try-catch,而是應(yīng)該在邊界層統(tǒng)一處理異常

1. 為什么異常值得單獨(dú)寫(xiě)一整個(gè)系列

在多數(shù)業(yè)務(wù)代碼中,異常往往被當(dāng)作一種“不得不寫(xiě)的語(yǔ)法”:

try {
    service.process();
} catch (Exception e) {
    log.error("error", e);
}

但在真實(shí)的 Web 系統(tǒng)中,異常從來(lái)不是一個(gè)語(yǔ)法問(wèn)題,而是一個(gè)系統(tǒng)失控時(shí)的兜底機(jī)制

一次 HTTP 請(qǐng)求,往往會(huì)經(jīng)歷如下鏈路:

  • Filter
  • Interceptor
  • Controller
  • 參數(shù)綁定與校驗(yàn)
  • Service
  • DAO
  • 事務(wù)
  • AOP 代理
  • JSON 序列化

異??梢栽谌魏我粋€(gè)環(huán)節(jié)出現(xiàn),而且一旦出現(xiàn),就會(huì)“逆著調(diào)用棧”向上冒泡,最終由框架決定:

  • 是否回滾事務(wù)
  • 是否返回 500
  • 返回什么格式
  • 是否記錄堆棧
  • 是否暴露錯(cuò)誤信息給前端

因此,異常不是“邊角料”,而是整個(gè)調(diào)用鏈的終點(diǎn)匯合處。

2. Java 異常模型的關(guān)鍵認(rèn)知(只講對(duì)后面有用的)

2.1 Throwable 體系結(jié)構(gòu)

Throwable
 ├── Error
 └── Exception
      ├── RuntimeException
      └── Checked Exception
  • Error:JVM 級(jí)錯(cuò)誤,應(yīng)用通常無(wú)能為力
  • Exception:應(yīng)用級(jí)異常
  • RuntimeException:Spring 默認(rèn)認(rèn)為這是“不可恢復(fù)異常”
  • Checked Exception:需要顯式聲明和處理

Spring 事務(wù)為什么默認(rèn)只對(duì) RuntimeException 回滾?
這個(gè)問(wèn)題在后面的事務(wù)異常章節(jié)會(huì)專門(mén)展開(kāi)。

2.2 異常傳播是“反向調(diào)用鏈”

正常調(diào)用是:

Controller → Service → DAO

異常傳播是:

DAO 拋異常 → Service → Controller → 框架

誰(shuí)最后接住異常,誰(shuí)就擁有最終解釋權(quán)。

3. 為什么 Web 系統(tǒng)不能到處 try-catch

3.1 try-catch 的三個(gè)常見(jiàn)問(wèn)題

  1. 吞異常,導(dǎo)致問(wèn)題被掩蓋
  2. 重復(fù)代碼,Controller 層異常處理泛濫
  3. 破壞事務(wù)回滾邏輯

例如:

@Transactional
public void createOrder() {
    try {
        saveOrder();
    } catch (Exception e) {
        log.error("error", e);
    }
}

這個(gè)代碼看起來(lái)穩(wěn)健,實(shí)際上事務(wù)已經(jīng)無(wú)法回滾。

3.2 異常必須“集中處理”

在 Web 架構(gòu)中,有一個(gè)非常重要的設(shè)計(jì)原則:

異常應(yīng)該在“邊界層”統(tǒng)一處理,而不是在業(yè)務(wù)層消化。

Spring MVC 正是基于這個(gè)原則,設(shè)計(jì)了一整套異常處理機(jī)制。

4. Spring MVC 的異常處理總體設(shè)計(jì)思想

4.1 正常流程 vs 異常流程

正常流程:

請(qǐng)求 → Handler → 返回值 → 響應(yīng)

異常流程:

請(qǐng)求 → Handler → 拋異常 → 異常解析 → 響應(yīng)

Spring MVC 的核心設(shè)計(jì)點(diǎn)在于:

異常不是 if-else 分支,而是一條獨(dú)立的處理鏈路。

4.2 異常處理在 DispatcherServlet 中的位置

DispatcherServlet 是整個(gè) MVC 的“總控中樞”。

在其核心方法 doDispatch 中,異常被統(tǒng)一捕獲:

try {
    // 查找 Handler 并執(zhí)行
} catch (Exception ex) {
    dispatchException = ex;
}

這意味著:

  • Controller 不需要感知異常如何返回
  • 框架會(huì)統(tǒng)一接管異常

5. Spring MVC 的三種基礎(chǔ)異常處理方式

5.1 直接拋出異常(推薦)

@GetMapping("/order")
public Order getOrder() {
    throw new IllegalArgumentException("參數(shù)錯(cuò)誤");
}

異常會(huì)交給框架處理,而不是在 Controller 內(nèi)部解決。

5.2 @ExceptionHandler:局部異常處理

@RestController
public class OrderController {

    @ExceptionHandler(IllegalArgumentException.class)
    public String handleIllegalArg(Exception e) {
        return e.getMessage();
    }
}

特點(diǎn):

  • 只對(duì)當(dāng)前 Controller 生效
  • 適合非常局部的異常場(chǎng)景

5.3 @ControllerAdvice:全局異常處理(重點(diǎn))

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ErrorResponse handle(Exception e) {
        return new ErrorResponse("500", e.getMessage());
    }
}

這是 Spring Boot 項(xiàng)目中最常見(jiàn)的異常處理入口。

6. @ControllerAdvice 的設(shè)計(jì)價(jià)值

6.1 為什么它是“全局異常處理”的核心

@ControllerAdvice 本質(zhì)上解決了三個(gè)問(wèn)題:

  1. 異常集中管理
  2. 返回格式統(tǒng)一
  3. 與業(yè)務(wù)邏輯解耦

6.2 多個(gè) ControllerAdvice 的順序問(wèn)題

Spring 支持定義多個(gè)全局異常處理器:

@Order(1)
@RestControllerAdvice
class BizExceptionHandler {}

@Order(2)
@RestControllerAdvice
class SystemExceptionHandler {}

優(yōu)先級(jí)越小,越先執(zhí)行。

7. 異常處理的第一版架構(gòu)形態(tài)

在“入門(mén)階段”,一個(gè)相對(duì)合理的異常架構(gòu)通常是:

Controller
   ↓
拋異常
   ↓
@ControllerAdvice
   ↓
統(tǒng)一錯(cuò)誤響應(yīng)

對(duì)應(yīng)的返回結(jié)構(gòu)示例:

{
  "code": "SYSTEM_ERROR",
  "message": "系統(tǒng)異常,請(qǐng)稍后再試"
}

8. 異常處理流程圖(概覽)

渲染錯(cuò)誤: Mermaid 渲染失敗: Parse error on line 5: ...Resolver] D --> E[@ExceptionHandler ----------------------^ Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'LINK_ID'

圖1 Spring MVC 異常處理基本流程圖

9. 本篇小結(jié)(從入門(mén)視角看異常)

到這里,我們只做了三件事:

  1. 糾正“異常只是 try-catch”的認(rèn)知
  2. 明確異常是 Web 系統(tǒng)的統(tǒng)一出口
  3. 理解 Spring MVC 為什么要集中處理異常

但我們還沒(méi)有回答幾個(gè)關(guān)鍵問(wèn)題:

  • 異常是如何一步步被解析的?
  • 為什么 @ExceptionHandler 能生效?
  • Spring Boot 的 /error 是干什么的?
  • 為什么有些異常進(jìn)不了 ControllerAdvice?

?? 這些問(wèn)題,都需要進(jìn)入源碼層面才能解釋清楚。

到此這篇關(guān)于Spring Boot異常處理try-catch應(yīng)該怎么使用?的文章就介紹到這了,更多相關(guān)Spring Boot異常處理try-catch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

參考資料

  • Spring Framework Reference – Exception Handling
    https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-exceptionhandler.html
  • Spring MVC 源碼(DispatcherServlet)
    https://github.com/spring-projects/spring-framework

相關(guān)文章

  • Java多線程中的原子類屬性說(shuō)明

    Java多線程中的原子類屬性說(shuō)明

    這篇文章主要介紹了Java多線程中的原子類屬性說(shuō)明,對(duì)多線程訪問(wèn)同一個(gè)變量,我們需要加鎖,而鎖是比較消耗性能的,JDk1.5之后,新增的原子操作類提供了一種用法簡(jiǎn)單、性能高效、線程安全地更新一個(gè)變量的方式,需要的朋友可以參考下
    2023-10-10
  • SpringBoot整合Swagger3生成接口文檔過(guò)程解析

    SpringBoot整合Swagger3生成接口文檔過(guò)程解析

    這篇文章主要介紹了SpringBoot整合Swagger3生成接口文檔過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 阿里SpringBoot應(yīng)用自動(dòng)化部署實(shí)現(xiàn)IDEA版Jenkins

    阿里SpringBoot應(yīng)用自動(dòng)化部署實(shí)現(xiàn)IDEA版Jenkins

    這篇文章主要為大家介紹了阿里SpringBoot應(yīng)用自動(dòng)化部署實(shí)現(xiàn)IDEA版Jenkins過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • JAVA中時(shí)間戳與LocalDateTime互相轉(zhuǎn)換代碼例子

    JAVA中時(shí)間戳與LocalDateTime互相轉(zhuǎn)換代碼例子

    最近在編碼過(guò)程中遇到將時(shí)間戳轉(zhuǎn)化為 LocalDateTime,所以這里給總結(jié)下,這篇文章主要給大家介紹了關(guān)于JAVA中時(shí)間戳與LocalDateTime互相轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java中sharding-jdbc 綁定表的實(shí)現(xiàn)

    Java中sharding-jdbc 綁定表的實(shí)現(xiàn)

    綁定表是 ShardingSphere-JDBC 解決跨庫(kù)表關(guān)聯(lián)查詢的核心機(jī)制,通過(guò)強(qiáng)制分片鍵和算法一致的表路由到同一物理庫(kù),實(shí)現(xiàn)高效本地關(guān)聯(lián),適用于大表之間的關(guān)聯(lián)場(chǎng)景,避免了全局表的存儲(chǔ)冗余,下面就來(lái)詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2026-03-03
  • 解讀Java中Set真的是無(wú)序的嗎

    解讀Java中Set真的是無(wú)序的嗎

    這篇文章主要介紹了Java中Set是不是無(wú)序的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Day16基礎(chǔ)不牢地動(dòng)山搖-Java基礎(chǔ)

    Day16基礎(chǔ)不牢地動(dòng)山搖-Java基礎(chǔ)

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Java高級(jí)特性之反射機(jī)制實(shí)例詳解

    Java高級(jí)特性之反射機(jī)制實(shí)例詳解

    這篇文章主要介紹了Java高級(jí)特性之反射機(jī)制,結(jié)合實(shí)例形式詳細(xì)分析了Java反射機(jī)制原理、功能、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-08-08
  • Java項(xiàng)目打包部署之部署jar包和war包

    Java項(xiàng)目打包部署之部署jar包和war包

    我們?cè)陂_(kāi)發(fā)環(huán)境部署項(xiàng)目一般通過(guò)ideal將項(xiàng)目打包成包,然后連接linux服務(wù)器,這篇文章主要給大家介紹了關(guān)于Java項(xiàng)目打包部署之部署jar包和war包的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • SpringBoot多數(shù)據(jù)源配置方式以及報(bào)錯(cuò)問(wèn)題的解決

    SpringBoot多數(shù)據(jù)源配置方式以及報(bào)錯(cuò)問(wèn)題的解決

    這篇文章主要介紹了SpringBoot多數(shù)據(jù)源配置方式以及報(bào)錯(cuò)問(wèn)題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評(píng)論

即墨市| 阿拉善左旗| 鸡西市| 灵石县| 乐都县| 广汉市| 师宗县| 安庆市| 梓潼县| 宕昌县| 长海县| 武胜县| 望都县| 乡城县| 泉州市| 彭山县| 林西县| 巴中市| 会东县| 麻阳| 绍兴市| 天全县| 临潭县| 宁化县| 德阳市| 乡城县| 达日县| 九台市| 黔南| 尉犁县| 勃利县| 江西省| 株洲市| 桃江县| 安康市| 淳化县| 齐河县| 修文县| 义马市| 长治市| 蒙自县|