aspectj切面异常统计的核心是在异常真实发生处精准采集上报,不干扰流程;通过@afterthrowing捕获,结合mdc traceid、方法名、异常类型实现链路级聚合分析。

用 AspectJ 切面做异常统计,核心不是“捕获并吞掉异常”,而是“在异常真实发生的位置,不干扰原有流程的前提下,精准采集、打标、上报”。它和 @ControllerAdvice 的全局捕获是互补关系:后者负责响应包装与兜底,前者专注可观测性建设——比如统计每类异常在哪个服务、哪个方法、什么时间段高频出现。
明确切点:只织入真正可能抛异常的业务方法
避免无差别拦截所有方法,重点锁定 Service 层或关键领域逻辑入口:
- 用
@Pointcut("execution(* com.example..service..*.*(..))")匹配 service 包下所有方法 - 可叠加条件,比如只统计带特定注解的方法:
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)") - 排除测试类、工具类等干扰项,防止统计失真
用 AfterThrowing 捕获异常并分类记录
不要用 Around 拦截再手动 throw,那会破坏原始调用栈。直接用 @AfterThrowing 在异常抛出后触发统计逻辑:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 获取异常类型:
ex.getClass().getSimpleName(),如NullPointerException、SQLException - 提取关键上下文:方法全名(
joinPoint.getSignature().toShortString())、traceId(从 MDC 或 RequestContextHolder 获取) - 记录到内存队列或异步发送到监控系统(如 Prometheus + Micrometer、ELK、自研埋点服务)
区分异常等级,避免噪音干扰
不是所有异常都值得报警或计入失败率:
- 业务异常(如
OrderNotExistException)通常不记为错误,只打日志+计数器,用于分析用户行为 - 系统异常(如
TimeoutException、Connection refused)才计入 error counter,并触发告警 - 可通过异常类继承体系或命名约定自动识别,比如所有以
System开头的异常视为严重异常
配合 MDC 实现链路级聚合统计
单靠方法名统计太粗粒度。把 traceId、method、exceptionType 三者组合为指标维度,就能查出“某个 trace 下为什么连续三次调用都抛了同一个异常”:
- 在 Controller 入口生成 traceId 并塞入 MDC:
MDC.put("traceId", id) - 切面中读取:
MDC.get("traceId"),和异常信息一起上报 - 监控平台按
traceId + exceptionType分组聚合,快速定位共性问题
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










