找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

748

积分

0

好友

100

主题
发表于 昨天 21:29 | 查看: 0| 回复: 0

云栈社区的技术交流中,自定义异常的处理层次是一个常见议题。其核心不在于具体放置在哪一层,而在于理解异常的本质:它描述了业务流程中为何无法继续执行。自定义业务异常通常定义在公共模块或业务层,由Service层抛出,并由接口层统一处理。

一、异常的核心作用是什么?

异常并非日志,也不是返回值的替代品。它只做一件事:中断当前流程,并说明“为什么不能继续”。因此,判断异常应该定义在哪一层的关键在于:谁最清楚“不能继续”的原因

二、为什么Controller层不适合定义业务异常?

很多开发者在初期可能会这样做:

throw new BizException("参数不合法");

将异常直接写在Controller里看似顺理成章,但实则存在问题:

  • Controller仅负责参数接收和请求转发,并不掌握完整的业务规则。
  • 同一业务规则可能被多个入口调用。
  • 导致异常逻辑分散、重复判断,修改规则时需改动多个接口。

Controller层不应成为业务判断的中心。

三、Service层:异常最合理的归属

正确的做法是在Service层抛出异常,例如:

@Service
public class OrderService {
    public void createOrder(Order order) {
        if (stock < order.getCount()) {
            throw new BizException("库存不足");
        }
    }
}

原因很明确:

  • Service层掌握完整的业务语义。
  • 它清楚哪些情况必须中断流程。
  • 它知道失败时是否需要回滚事务。

只有在Service层抛出的异常,才是真正的“业务异常”。

Controller层则只需简单调用:

@PostMapping("/order/create")
public Result<?> create() {
    orderService.createOrder(order);
    return Result.success();
}

四、异常类本身的存放位置

1. 公共业务异常(通用型)

com.xxx.common.exception.BizException

适用于参数不合法、状态不允许、权限不足等通用场景,可被多个模块复用。

2. 模块级业务异常(复杂业务)

com.xxx.order.exception.OrderException

当某个业务领域异常众多、语义强烈时,可单独拆分为模块级异常。但前提是:异常必须使用“业务语言”描述,而非技术分类。

五、哪些地方不应定义业务异常?

❌ Mapper层

Mapper仅负责数据访问,不理解业务语义。它可以抛出系统异常(如SQL异常),但不该抛出业务异常

❌ 工具类或Util

工具类只提供通用能力,不涉及业务规则。一旦在其中抛出业务异常,其复用性将大打折扣。

总结来说,异常属于业务逻辑范畴,不应定义在接口层或数据层,而应归属于掌握业务语义的Service层。




上一篇:UART I2C SPI CAN RS485通信协议选型、调试与实战避坑指南
下一篇:联想ThinkBook 16P 2024款体验:3.2K高刷大屏配i9+4060,移动工作站新选择?
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-25 21:51 , Processed in 0.256929 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表