一、JAVA异常体系
(1)异常处理流程图
(2)异常处理机制
(3)异常处理体系
二、异常处理
(1)异常处理原则
- 非必要使用异常
- 使用描述性消息抛出异常
- 力所能及的异常一定要处理
- 异常的忽略需要有理有据
(2)异常处理的一些特殊情况
1. try....catch....finally流程解析
2. try with resource 执行流程
3. 级联调用时易产生 NPE
连续的参数判断,可读性很差,代码也不优美,怎么改善?
jdk8使用optional类可以优雅的防止以上连续属性调用出现的NPR问题。
例子:
4.foreach遍历循环
- 不要在foreach循环中进行元素的remove/add
- foreach循环会自动跳过遍历空集合,如果对于有null值的集合,碰到null时需注意NPE
- 在foreach循环中,抛出异常会中断程序
三、日志规约
(1)日志的功能
(2)日志时效规约
因为金融等一些特殊的业务,会要求敏感信息存储6个月以上。
系统日志信息应该依赖日志框架,而不是具体的API。
(3)日志记录的规约
- 系统应依赖使用日志框架(SLF4J、JCL)的API,而不是具体日志库中的。
- 日志输出时,字符变量之间的拼接会用占位符方式。
- 日志打印禁止使用JSON将对象转为STRING
- 尽量用英文描述
(4)logback日志框架解析
(5)输出规约
- 对于trace/debuf/info级别的日志输出,必须进行日志级别开关判断
- 异常日志信息必须完整,包含案发现场信息,堆栈信息
- 避免打重复日志,浪费磁盘空间
四、错误码规约
- 定义时,要有字母也要有数字
- 要分级分类管理
- 不能直接输出给用户作为提示信息使用
- 不要与业务架构或者组织架构挂钩
- 避免随意定义新的错误码
- 便于不同语言的开发者间写作
五、异常与日志综合实践
(1)在controller层统一捕获异常
(2)全局异常处理组件globalExceptionHandler 的定义和使用
(3)API层异常设计实践
(4)service层异常设计实践
(5)DAO数据处理层异常、日志实践
- 使用DaoException,使用继承自runtime Exception的通用DaoException封装dao层异常并向上抛出
- 框架层面有选择有选择记录数据操作,如sql或者执行时间
(6)使用MDC实现轻量级调用链路追踪
分布式链路追踪:将一次分布式请求还原成调用链路,将一次分布式请求的调用 情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。
功能:
- 故障快速定位
- 链路性能优化可视
- 链路分析
(7) 用有限的异常类处理业务中复杂多变的无限可能
-
通用ServiceException,定义继承自RuntimeException的 通用ServiceException。
-
结合与业务关联的ErrorCode实现复杂多变的业务异常需求。通用ServiceException业务异常