@AfterThrowing用于异常时记录日志,需显式声明throwing属性绑定异常,配合JoinPoint获取上下文,结合切点精准定位;需与@Around协同实现异常拦截与转换。
Spring AOP 提供了优雅的方式,在不侵入业务代码的前提下统一处理异常并记录日志。关键在于用
捕获异常,配合环绕通知或切点表达式精准定位目标方法,再通过参数注入(如
、异常对象)实现上下文感知的日志增强。
明确异常通知的触发条件
是专为异常场景设计的通知类型,它只在目标方法抛出指定异常时执行,不会干扰正常流程。这点区别于
(总会执行)或
(需手动控制流程)。
必须显式声明
属性,绑定异常形参,否则无法获取异常实例
切点表达式应聚焦具体层,例如
或更细粒度的
若需捕获自定义异常,确保异常类在切点范围内被抛出,且未被上层 try-catch 吞掉
注入异常与执行上下文变量
Spring AOP 允许在通知方法中直接接收运行时信息,无需手动反射提取:
:提供方法签名、参数值、目标对象等基础信息
:由
绑定,可调用
、
等
还可结合
获取当前 HTTP 请求信息(Web 环境下)
构建可读性强的日志内容
避免只打印堆栈,应结构化输出关键诊断字段:
记录完整方法签名:
打印入参快照(注意脱敏敏感字段,如密码、身份证号)
包含异常类型、消息、时间戳、请求唯一 ID(如 traceId)便于链路追踪
示例日志格式:
与环绕通知协同做异常兜底
仅靠
无法修改返回值或阻止异常传播。如需统一转换异常为响应体(如 REST API 返回标准错误码),推荐用
包裹逻辑:
在
后 catch 异常,做日志 + 转换,再 rethrow 或返回友好结果
若既要记录日志又要拦截异常,
更灵活;若只需旁观式记录,
更轻量、语义清晰
两者可共存:环绕用于控制流,异常通知用于审计留痕
@AfterThrowingJoinPoint@AfterThrowing@After@Aroundthrowing@within(org.springframework.stereotype.Service)execution(* com.example.service..*.*(..))JoinPoint joinPointThrowable exceptionthrowing="exception"getMessage()getStackTrace()RequestContextHolderjoinPoint.getSignature().toShortString()[ERROR] ServiceException in UserService.updateUser(id=123): Validation failed - email format invalid@AfterThrowing@Aroundproceed()@Around@AfterThrowing