it编程 > 编程语言 > Java

Spring Boot异常处理try-catch应该怎么使用?

8人参与 2026-01-31 Java

1. 为什么异常值得单独写一整个系列

在多数业务代码中,异常往往被当作一种“不得不写的语法”:

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

但在真实的 web 系统中,异常从来不是一个语法问题,而是一个系统失控时的兜底机制

一次 http 请求,往往会经历如下链路:

异常可以在任何一个环节出现,而且一旦出现,就会“逆着调用栈”向上冒泡,最终由框架决定:

因此,异常不是“边角料”,而是整个调用链的终点汇合处

2. java 异常模型的关键认知(只讲对后面有用的)

2.1 throwable 体系结构

throwable
 ├── error
 └── exception
      ├── runtimeexception
      └── checked exception

spring 事务为什么默认只对 runtimeexception 回滚?
这个问题在后面的事务异常章节会专门展开。

2.2 异常传播是“反向调用链”

正常调用是:

controller → service → dao

异常传播是:

dao 抛异常 → service → controller → 框架

谁最后接住异常,谁就拥有最终解释权。

3. 为什么 web 系统不能到处 try-catch

3.1 try-catch 的三个常见问题

  1. 吞异常,导致问题被掩盖
  2. 重复代码,controller 层异常处理泛滥
  3. 破坏事务回滚逻辑

例如:

@transactional
public void createorder() {
    try {
        saveorder();
    } catch (exception e) {
        log.error("error", e);
    }
}

这个代码看起来稳健,实际上事务已经无法回滚

3.2 异常必须“集中处理”

在 web 架构中,有一个非常重要的设计原则:

异常应该在“边界层”统一处理,而不是在业务层消化。

spring mvc 正是基于这个原则,设计了一整套异常处理机制。

4. spring mvc 的异常处理总体设计思想

4.1 正常流程 vs 异常流程

正常流程:

请求 → handler → 返回值 → 响应

异常流程:

请求 → handler → 抛异常 → 异常解析 → 响应

spring mvc 的核心设计点在于:

异常不是 if-else 分支,而是一条独立的处理链路。

4.2 异常处理在 dispatcherservlet 中的位置

dispatcherservlet 是整个 mvc 的“总控中枢”。

在其核心方法 dodispatch 中,异常被统一捕获:

try {
    // 查找 handler 并执行
} catch (exception ex) {
    dispatchexception = ex;
}

这意味着:

5. spring mvc 的三种基础异常处理方式

5.1 直接抛出异常(推荐)

@getmapping("/order")
public order getorder() {
    throw new illegalargumentexception("参数错误");
}

异常会交给框架处理,而不是在 controller 内部解决。

5.2 @exceptionhandler:局部异常处理

@restcontroller
public class ordercontroller {

    @exceptionhandler(illegalargumentexception.class)
    public string handleillegalarg(exception e) {
        return e.getmessage();
    }
}

特点:

5.3 @controlleradvice:全局异常处理(重点)

@restcontrolleradvice
public class globalexceptionhandler {

    @exceptionhandler(exception.class)
    public errorresponse handle(exception e) {
        return new errorresponse("500", e.getmessage());
    }
}

这是 spring boot 项目中最常见的异常处理入口

6. @controlleradvice 的设计价值

6.1 为什么它是“全局异常处理”的核心

@controlleradvice 本质上解决了三个问题:

  1. 异常集中管理
  2. 返回格式统一
  3. 与业务逻辑解耦

6.2 多个 controlleradvice 的顺序问题

spring 支持定义多个全局异常处理器:

@order(1)
@restcontrolleradvice
class bizexceptionhandler {}

@order(2)
@restcontrolleradvice
class systemexceptionhandler {}

优先级越小,越先执行。

7. 异常处理的第一版架构形态

在“入门阶段”,一个相对合理的异常架构通常是:

controller
   ↓
抛异常
   ↓
@controlleradvice
   ↓
统一错误响应

对应的返回结构示例:

{
  "code": "system_error",
  "message": "系统异常,请稍后再试"
}

8. 异常处理流程图(概览)

图1 spring mvc 异常处理基本流程图

9. 本篇小结(从入门视角看异常)

到这里,我们只做了三件事:

  1. 纠正“异常只是 try-catch”的认知
  2. 明确异常是 web 系统的统一出口
  3. 理解 spring mvc 为什么要集中处理异常

但我们还没有回答几个关键问题:

👉 这些问题,都需要进入源码层面才能解释清楚。

到此这篇关于spring boot异常处理try-catch应该怎么使用?的文章就介绍到这了,更多相关spring boot异常处理try-catch内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

参考资料

(0)

您想发表意见!!点此发布评论

推荐阅读

Java多重数组使用及说明

01-31

Java自动化设置PDF文档属性的示例代码

01-31

Spring Boot全局异常处理机制中DispatcherServlet的处理流程和作用

01-31

java的多重注解(重复注解)详解

01-31

MyBatis中批量插入的三个关键优化技巧与避坑指南

01-31

SpringBoot设置欢迎页的三种方式详解

01-31

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论