Spring Boot中如何修改已有Aspect实现方法调用异常的日志记录
实现方案
你只需要在@Around通知的代码中用try-catch块包裹目标方法执行逻辑,捕获到异常后打印异常日志,再把原异常重新抛出即可,不要吞异常,否则会影响原有业务逻辑的正常执行。
修改后的完整代码
@Aspect @Component public class LogAdvice { Logger logger = LoggerFactory.getLogger(LogAdvice.class); // 可选优化:将ObjectMapper提取为成员变量,避免重复创建对象 private final ObjectMapper mapper = new ObjectMapper(); @Pointcut(value = "execution(* com.learning.spring.*.*.*(..))") public void pointCut() { } @Around("pointCut()") public Object appLogger(ProceedingJoinPoint jp) throws Throwable { String methodName = jp.getSignature().getName(); String className = jp.getTarget().getClass().toString(); Object[] args = jp.getArgs(); logger.info("Start call: " + className + ":" + methodName + "()" + " with arguments: " + mapper.writeValueAsString(args)); Object object = null; try { object = jp.proceed(); logger.info("End call: " + className + ":" + methodName + "()" + " returned: " + mapper.writeValueAsString(object)); } catch (Throwable e) { // 记录异常信息,error级别日志,传入异常对象e可打印完整堆栈 logger.error("Exception occurred in call: " + className + ":" + methodName + "()" + " exception message: " + e.getMessage(), e); // 必须重新抛出原异常,避免破坏原有业务逻辑的异常传递 throw e; } return object; } }
注意点
- 异常日志建议使用
error级别,和普通的info调用日志做区分,方便排查问题 - 打印日志时一定要把异常对象
e作为最后一个参数传给logger,这样才能打印完整的堆栈信息,不要只打印e.getMessage(),会丢失排查问题的关键信息 - 捕获异常后必须重新抛出原异常,不能吞掉,否则原本应该抛出的异常会被拦截,上层业务逻辑收不到异常通知,会出现逻辑错误
- 如果有特殊需求需要修改异常内容,也建议抛出自定义业务异常,不要直接吞掉不抛出
内容的提问来源于stack exchange,提问作者pixel
相关产品推荐
相关产品推荐

