Java自定义异常日志统一封装的核心是收口异常捕获、日志输出、上下文补充和响应处理:通过@ControllerAdvice统一拦截、MDC增强日志上下文、工具类联动抛异常与打日志,并为非Web场景提供AOP或主动try-catch兜底方案。

Java 自定义异常的日志记录统一封装,核心是把异常捕获、日志输出、上下文补充和响应处理这几个环节收口到一个可控的点,避免到处 log.error("xxx", e) 或 e.printStackTrace() 这类散落写法。
统一异常处理器(@ControllerAdvice + @ExceptionHandler)
适用于 Spring Web 项目,集中拦截 Controller 层抛出的自定义异常,并做标准化日志记录和响应封装:
- 定义自定义异常类(如
BusinessException),继承RuntimeException,支持携带错误码、提示信息、扩展参数 - 用
@ControllerAdvice声明全局异常处理器,在其中用@ExceptionHandler(BusinessException.class)拦截 - 在处理方法中统一调用日志框架(如 SLF4J)记录完整上下文:异常类型、错误码、消息、请求路径、用户ID(如有)、traceId(配合 MDC)
- 示例关键代码:
log.error("业务异常[{}],msg={},path={},uid={},traceId={}",
e.getErrorCode(), e.getMessage(), request.getRequestURI(),
SecurityContext.getUserId(), MDC.get("traceId")), e);
日志上下文增强(MDC + Filter/Interceptor)
让每条日志自动带上请求唯一标识和关键业务字段,无需每次手动传参:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 在 WebFilter 或 HandlerInterceptor 中生成并注入
traceId、requestId、userId等到 MDC - 确保日志配置(如 logback.xml)中 pattern 包含
%X{traceId}等占位符 - 异常发生时,即使没显式打印,日志里也天然带上下文,便于链路追踪和问题定位
- 注意在线程切换(如异步、线程池)时需手动传递 MDC 内容,可用
MDC.getCopyOfContextMap()保存再恢复
异常构造与日志联动(推荐封装工具类)
避免开发者手动 new 异常 + 单独打日志,把“抛异常”和“记日志”逻辑绑定:
- 提供静态工具方法,如
Exceptions.business("USER_NOT_FOUND").withParam("uid", 123).throwAndLog(); - 内部完成三件事:构建异常对象、用 SLF4J 记录带上下文的 ERROR 日志、再 throw 出去
- 可选支持自动填充当前类名、方法名、行号(通过
Thread.currentThread().getStackTrace()获取) - 这样既保证日志必打,又避免漏掉异常信息或上下文缺失
非 Web 场景(Service/Job/Utils)的兜底方案
对于非 Controller 的普通方法(如定时任务、工具类),无法依赖 @ControllerAdvice,需主动防御:
- 约定所有 service 方法入口加 try-catch(慎用,仅关键路径),捕获自定义异常后统一 log.error + rethrow
- 使用 AOP 对指定包下的方法做环绕通知,捕获异常后按规则记录日志(注意避免影响性能和吞吐)
- 对关键第三方调用(如 HTTP、DB)做包装,失败时统一转为自定义异常并记录详细入参和响应体
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










