AOP实现注解日志功能

写项目时,需要添加日志功能,具体需求是:在方法上添加注解,当该方法执行时,控制台答应该方法的具体信息。

需求分析:实现该功能需要使用AOP,以注解为切点,环绕添加注解的方法实现日志功能。

注解实现


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SystemLog {
  String businessName(); // 添加注解时,使用该方法返回方法的功能
}

切面类

@Component
@Aspect
@Slf4j
public class LogAspect {
@Pointcut("@annotation(com.wz.blogcommon.annotation.SystemLog)") // 以该注解类为切点
public void pt() {
}
@Around("pt()") // 环绕切点实现日志功能的添加
public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {
Object ret;
try {
  handleBefore(joinPoint);
  ret = joinPoint.proceed();
  handleAfter(ret);
} finally {
  // 结束后换行
  log.info("=======End=======" + System.lineSeparator());
}
  return ret;
}

private void handleAfter(Object proceed) {
  // 打印出参
  log.info("Response : {}", JSON.toJSONString(proceed));
}

private void handleBefore(ProceedingJoinPoint joinPoint) {
  ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  assert requestAttributes != null;
  HttpServletRequest request = requestAttributes.getRequest();
  SystemLog systemLog = getSystemLog(joinPoint);
  log.info("=======Start=======");
  // 打印请求 URL
  log.info("URL : {}", request.getRequestURI());
  // 打印描述信息
  log.info("BusinessName : {}", systemLog.businessName());
  // 打印 Http method
  log.info("HTTP Method : {}", request.getRequestURI());
  // 打印调用 controller 的全路径以及执行方法
  log.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
  // 打印请求的 IP
  log.info("IP : {}", request.getRemoteHost());
  // 打印请求入参
  // TODO 参数为MultipartFile时无法打印,抛出异常
  log.info("Request Args : {}", !(joinPoint.getArgs().length > 0 && joinPoint.getArgs()[0] instanceof MultipartFile) ? JSON.toJSONString(joinPoint.getArgs()) : "文件上传请求,请求参数略");
}

private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) {
  MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  Method method = methodSignature.getMethod();
  return method.getAnnotation(SystemLog.class);
}
}
posted @   新游  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示