Aop+自定义注解实现查看操作日志

2022-11-21 10:18:17

一、自定义注解

1、注解分为元注解和自定义注解,而元注解可以进入到你经常使用到的springboot注解中查看,在注解源码最上方,可以看到有这三个注解出现,而这三个注解是jdk提供的,包是package java.lang.annotation;
在这里插入图片描述
(1)@Target: 指明注解的作用域,也就是可以指定自定义注解用于什么位置,类、方法、字段,可以指定多种。
(2)@Retention 指定自定义注解在什么时候生效,也就是指定他的生命周期,首先要明白要跑一个java文件,是先编译变为.class文件,也就是字节码文件,然后再通过jvm去执行这个文件,而你经常听到的运行时异常的运行时,其实就是在执行这个.class文件出现的异常,而编译时异常则是在编译为.class时出现异常。详情查看
现在回到这个注解,这三种参数都是什么?
其实常用的就是RUNTIME ,这是指在经过编译之后,通过jvm执行之后仍然会保留着,而Source 是指在编译时便被丢弃;而CLASS 则是在编译的时候会保留在.class文件中,但是通过jvm执行时会被丢弃。
在这里插入图片描述
(3)@Documented: 这个起到一个标注作用,下面是源码的解释
在这里插入图片描述
2、自定义注解

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documentedpublic@interfaceCustomAnnotation{}

二、使用AOP查看操作日志

先明白思路,要实现操作日志,也就是我们需要在他进行操作的过程中获取他的请求、他请求调用的全限定名、传入的参数,最后返回的参数是什么,也就是在他操作的整个过程,咱们都需要参与,那就是用到了注解@Around详情查看

packagecom.example.demo.config;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Pointcut;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.stereotype.Component;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletRequest;@Aspect@ComponentpublicclassAopLog{privateLogger logger=LoggerFactory.getLogger(this.getClass());//slf4j的日志打印ThreadLocal<Long> startTime=newThreadLocal<>();//创建一个子线程来存时间@Around("@annotation(CustomAnnotation)")publicObjectmyLogger(ProceedingJoinPoint joinPoint)throwsThrowable{
        startTime.set(System.currentTimeMillis());//计时,存下当前时间ServletRequestAttributes attributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();//绑定当前线程的请求的对象HttpServletRequest request= attributes.getRequest();String className= joinPoint.getSignature().getDeclaringTypeName();//获取请求的类的完全限定名String methodName= joinPoint.getSignature().getName();//请求的方法Object[] array= joinPoint.getArgs();//传入的参数ObjectMapper mapper=newObjectMapper();//执行函数前打印日志
        logger.info("调用前:{}:{},传递的参数为:{}", className, methodName, mapper.writeValueAsString(array));
        logger.info("URL:{}", request.getRequestURL().toString());
        logger.info("IP地址:{}", request.getRemoteAddr());//调用整个目标函数执行Object obj= joinPoint.proceed();//执行函数后打印日志
        logger.info("调用后:{}:{},返回值为:{}", className, methodName, mapper.writeValueAsString(obj));
        logger.info("耗时:{}ms",System.currentTimeMillis()- startTime.get());return obj;}}
  • 作者:单俞浩
  • 原文链接:https://blog.csdn.net/weixin_44975592/article/details/125355304
    更新时间:2022-11-21 10:18:17