news 2026/6/9 22:46:49

Spring的异常处理机制详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring的异常处理机制详解

在Spring Boot MVC架构中,如果Service方法中的异常没有被捕获也没有被抛出,异常的处理流程如下:

1.默认异常处理流程

@RestControllerpublicclassUserController{@AutowiredprivateUserServiceuserService;@GetMapping("/user/{id}")publicUsergetUser(@PathVariableLongid){// 如果Service抛出异常且没有被捕获returnuserService.findById(id);// 异常会向上传播}}@ServicepublicclassUserService{publicUserfindById(Longid){// 这里发生异常(比如NullPointerException)// 但没有try-catch,也没有声明throwsreturnuserRepository.findById(id).orElseThrow(()->newRuntimeException("User not found"));}}

2.异常的传播路径

Service层异常 → Controller层 → DispatcherServlet → 框架处理

具体处理方式:

3.运行时异常(RuntimeException)

@ServicepublicclassUserService{publicvoidprocess(){// 运行时异常会自动向上传播intresult=10/0;// ArithmeticException}}

处理结果

  • 异常会传播到Controller
  • 如果没有@ExceptionHandler处理,会到DispatcherServlet
  • 最终返回HTTP 500状态码

4.受检异常(Checked Exception)

@ServicepublicclassUserService{publicvoidreadFile(){// 编译错误:必须处理或声明抛出// FileReader fr = new FileReader("file.txt");}publicvoidreadFile2()throwsIOException{// 必须声明throwsFileReaderfr=newFileReader("file.txt");}}

关键区别

  • 受检异常:编译时会报错,必须处理
  • 运行时异常:编译通过,运行时才暴露

5.Spring的异常处理机制

A. Controller级别的@ExceptionHandler

@RestControllerAdvicepublicclassGlobalExceptionHandler{@ExceptionHandler(RuntimeException.class)publicResponseEntity<String>handleRuntimeException(RuntimeExceptione){returnResponseEntity.status(500).body("Service Error: "+e.getMessage());}}

B. Service层使用声明式事务

@Service@TransactionalpublicclassUserService{publicvoidupdateUser(Useruser){// 事务方法中的异常会导致事务回滚userRepository.save(user);thrownewRuntimeException("Test rollback");}}

6.实际影响和最佳实践

不推荐的做法

@ServicepublicclassUserService{publicvoidriskyMethod(){// 异常被"吞掉",调用方不知道出错try{// 可能抛出异常的操作}catch(Exceptione){// 空的catch块,不记录也不抛出}}}

推荐的最佳实践

方案1:统一异常处理
@ServicepublicclassUserService{publicUserfindById(Longid){returnuserRepository.findById(id).orElseThrow(()->newUserNotFoundException("User not found with id: "+id));}}// 自定义业务异常publicclassUserNotFoundExceptionextendsRuntimeException{publicUserNotFoundException(Stringmessage){super(message);}}
方案2:使用AOP统一处理
@Aspect@ComponentpublicclassServiceExceptionAspect{@AfterThrowing(pointcut="execution(* com.example.service.*.*(..))",throwing="ex")publicvoidhandleServiceException(Exceptionex){// 记录日志、监控等log.error("Service层异常: ",ex);}}
方案3:响应式异常处理
@ServicepublicclassUserService{@TransactionalpublicUsercreateUser(UserDTOdto){try{// 业务逻辑returnuserRepository.save(user);}catch(DataIntegrityViolationExceptione){thrownewBusinessException("用户已存在",e);}catch(Exceptione){log.error("创建用户失败",e);thrownewSystemException("系统错误,请稍后重试",e);}}}

7.重要结论

  1. 运行时异常:会自动传播,最终返回HTTP 500
  2. 受检异常:编译时强制要求处理
  3. 默认响应:未处理的异常会生成包含错误详情的HTTP 500响应
  4. 事务影响:Spring事务管理会回滚运行时异常
  5. 日志记录:异常栈会记录在服务器日志中

建议:即使在Service层,也应该适当处理异常,至少记录日志,并根据业务需要转换为合适的业务异常再向上抛出。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 15:09:46

【谁懂啊!科研狗的降重血泪史谁能破?】

熬夜改了 3 遍的论文&#xff0c;查重率依然飙到 28%&#xff1b; 逐句改写半天&#xff0c;专业术语全变味&#xff0c;导师直接打回&#xff1a;“逻辑混乱&#xff01;”&#xff1b; 手动删重复、调语序&#xff0c;越改越崩溃&#xff0c; deadline 就在眼前... 作为常…

作者头像 李华
网站建设 2026/6/9 21:35:01

云徙科技:企业全链路AI解决方案赋能伙伴

云徙科技成立于2016年&#xff0c;是企业全链路AI解决方案的赋能伙伴&#xff0c;国家级专精特新“小巨人”企业&#xff0c;提供从咨询规划到生态搭建&#xff0c;从应用服务到基础设施、从营销到业财的全链路解决方案&#xff0c;致力于成为企业AI转型最受信赖的⻓期共创伙伴…

作者头像 李华
网站建设 2026/6/9 17:03:19

【课程设计/毕业设计】基于springboot的居民小区物业管理系统的设计与实现“物业办公 - 业主服务 - 数据监管” 三位一体的数字化架构【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/5 21:12:38

乐享云 v1.1.0| 不限速磁力下载,边下边播,内置字幕匹配

这是一款最近新出的免费磁力软件&#xff0c;目前仅提供安卓版。注册登录之后即可无限制使用。只需将磁力链接复制到软件中&#xff0c;等待软件解析完磁力链接后就可以打开磁力文件。如果磁力文件中包含视频资源&#xff0c;软件支持直接在线预览观看视频。同时&#xff0c;软…

作者头像 李华
网站建设 2026/6/5 19:39:16

Python返回数组/List长度的方法

你想了解在 Python 中获取列表&#xff08;List&#xff0c;也常被俗称 “数组”&#xff09;长度的方法&#xff0c;这是 Python 基础中高频使用的操作&#xff0c;核心是通过内置函数实现&#xff0c;同时需要掌握不同场景下的使用细节&#xff08;比如嵌套列表、numpy 数组等…

作者头像 李华