Aop+自定义注解实现日志收集

1:导入依赖

 
 
    org.springframework.boot
    spring-boot-starter-aop
 
     


    org.projectlombok
    lombok
    provided 

2:自定义注解

 /**
  *日志标记注解,只有打上了这个注解,才会进行日志收集
  */
 //type代表可以放在类上,方法上
 @Target({ElementType.METHOD,ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface LogAnnotation {
 ​
 }
 @Documented – 注解是否将包含在JavaDoc中
 @Retention – 什么时候使用该注解
 @Target – 注解用于什么地方,可作用于方法,类上
 @Inherited – 是否允许子类继承该注解
 @Target({ElementType.XXX})

Aop+自定义注解实现日志收集_第1张图片

3:定义切面

import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 import javax.servlet.http.HttpServletRequest;
 ​
 @Aspect  //切面 定义了通知和切点的关系
 @Slf4j    //用于日志收集
 @Component
 public class LogAspect {
 ​
     ThreadLocal startTime = new ThreadLocal<>();
 ​
     //指定切点,是哪个注解,这里指定我们刚自定义声明的注解
     @Pointcut("@annotation(com.bzovo.eduservice.log.LogAnnotation)")
     public void pointcut(){
     }
 ​
     //环绕通知,可以对方法前后做一个增强
     @Around("pointcut()")
     public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
         startTime.set(System.currentTimeMillis());
         //使用ServletRequestAttributes请求上下文获取方法更多
         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 = new ObjectMapper();
         //执行函数前打印日志
         log.info("调用前:{}:{},传递的参数为:{}", className, methodName, mapper.writeValueAsString(array));
         log.info("URL:{}", request.getRequestURL().toString());
         log.info("IP地址:{}", request.getRemoteAddr());
         //调用整个目标函数执行
         Object obj = joinPoint.proceed();
         //执行函数后打印日志
         log.info("调用后:{}:{},返回值为:{}", className, methodName, mapper.writeValueAsString(obj));
         log.info("耗时:{}ms", System.currentTimeMillis() - startTime.get());
         return obj;
     }
 }

4:在我们的方法上加上我们刚自定义的注解,观察效果

Aop+自定义注解实现日志收集_第2张图片

启动项目,这里是一个Get请求,我们使用swagger来测试或者postman来观察控制台输出

Aop+自定义注解实现日志收集_第3张图片

实际项目中,我们也可以新建一个实体对应db中一张表,来记录我们的操作.

你可能感兴趣的:(java,spring,boot)