AOP记录日志

2022-08-06  本文已影响0人  小名源治

AOP:面向切面编程,在不改变原有方法的基础上增强原有方法。

代码实现

1.自定义日志注解注解

1.1添加元注解(基础注解)@Target、@Retention、@Documented
元注解的作用就是负责注解其他注解
@Target:用于描述注解的使用范围,该注解可以使用在什么地方
@Retention:表明该注解的生命周期
@Documented:表明该注解标记的元素可以被Javadoc 或类似的工具文档化
1.2添加两个自定义参数
module 模块
operator 操作名称

@Target(ElementType.METHOD) // 这里的METHOD代表该自定义注解可以放在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {

    //自定义两个参数(默认值为空),使用此注解的时候就可以携带参数

    String module() default "";

    String operator() default "";
}

2.AOP切面

切面定义了通知和切点的关系
简单的理解使用 @Aspect 注解的类就是切面
切入点:使用@Pointcut()注解标识我们的切点,并且指向我们自定义的注解
通知:在通知类上面使用@Around()标识切点,通过切点就能执行我们的通知类。
通过反射机制,拿到注解的方法,可以知道模块名和具体操作
通过传递的参数ProceedingJoinPoint(连接点)得到请求的相关信息
最后利用@Slf4j 打印日志。

@Aspect  
@Component //添加为组件
@Slf4j  //日志
public class LogAspect {

    /**
     * 切点
     */
    @Pointcut("@annotation(com.example.myblog.common.aop.LogAnnotation)")
    public void logPointCut() {
    }

    /**
     * 通知类
     * 环绕通知  能对我们的方法前后都进行增强
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("logPointCut()")  //标识切点
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法 调用我们原有的方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        recordLog(point, time);
        return result;
    }

    private void recordLog(ProceedingJoinPoint joinPoint, long time) {
        //通过反射的形式拿到我们的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        log.info("=====================log start================================");
        log.info("module:{}",logAnnotation.module()); //模块名
        log.info("operation:{}",logAnnotation.operator());  //具体操作

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();  //请求的接口名称
        String methodName = signature.getName();  //请求的方法名称
        log.info("request method:{}",className + "." + methodName + "()");

//        //请求的参数
        Object[] args = joinPoint.getArgs();
        String params = JSON.toJSONString(args[0]); //转化成JSON格式
        log.info("params:{}",params);

        log.info("excute time : {} ms",time);
        log.info("=====================log end================================");
    }

}

3.使用(在方法上使用)

  @PostMapping()
    //加上此注解代表要对此接口记录日志
    @LogAnnotation(module="文章", operator="获取文章列表") //(模块名称,操作参数)
    public Result articles(@RequestBody PageParams pageParams) {
        //ArticleVo 页面接收的数据
        List<ArticleVO> articles = articleService.listArticlesPage(pageParams);

        return Result.success(articles);
    }

4.结果

image.png

参考文章: 这里

上一篇 下一篇

猜你喜欢

热点阅读