Spring异常处理探索与思考

	抛出或捕获异常的时候,有很多不同的事情需要考虑,而且大部分事情都是为了改善代码的可读性或者 API 的可用性。

不足

  • 分类不明确
  • 使用混乱

原则

三个原则是:
● 具体明确——层次清晰
● 提早抛出——迅速失败
● 延迟捕获——统一处理

异常要回答以下三个问题:

● 什么出了错?
● 在哪出的错?
● 为什么出错?

异常类型回答了“什么”被抛出,
异常堆栈回答了“在哪儿“抛出,
异常信息回答了“为什么“抛出

实践

1、在 Finally 中清理资源或使用 Try-With-Resource 语句
2、抛出明确的异常
3、为方法签名中的指定异常添加文档
4、抛出异常时使用描述性消息
5、优先捕获具体的异常
6、不要捕获 Throwable
7、不要忽略异常
8、不要同时打印并抛出异常
9、封装异常但不要丢弃原始异常

处理

异常统一处理方式

  • Before Spring 3.2
    Solution 1 – The Controller level @ExceptionHandler
    Solution 2 – The HandlerExceptionResolver

  • After Spring 3.2
    Solution 3 – @ControllerAdvice

注意

优先级
Solution 1
Solution 3
Solution 2

异常处理先使用1,匹配不到再找3, 再找2

看源码
优先Solution 1,然后Solution 3
Spring异常处理探索与思考_第1张图片

加载handlerExceptionResolvers, 并排序
Spring异常处理探索与思考_第2张图片

冲突

a. Solution 1 和 3 内定义同类型的 Exception 处理器(方法名不同)

Solution 1 运行时抛异常:IllegalStateException: Ambiguous @ExceptionHandler method

Solution 3 启动报错

b. Solution 1 和 3 内定义ExceptionHandler/SubExceptionHandler

处理SubException,则使用更具体的 SubExceptionHandler

设计

异常加code 字段, 业务区分

  • 展示给用户的异常
    UserException

请求参数错误
ParameterException
提交表单数据错误
FieldNotValidException
权限受控
AccessDeniedException
更新保存失败
OperationFailedException
查无数据
ContentNotFoundException

  • 不是展示给用户的异常

业务非预期异常

InternalException
NonUserException

References

  • https://www.cnblogs.com/andy-zhou/p/5317820.html

  • https://community.oracle.com/docs/DOC-983219

  • https://dzone.com/articles/9-best-practices-to-handle-exceptions-in-java

  • https://www.baeldung.com/exception-handling-for-rest-with-spring

  • https://www.javaworld.com/article/2077793/core-java/exceptions-for-action.html

  • http://www.importnew.com/1701.html

  • http://www.importnew.com/29603.html

  • https://www.oschina.net/question/12_37141

你可能感兴趣的:(Java)