当前位置: 首页 > article >正文

日志模块自定义@SkipLogAspect注解跳过切面

文章目录

    • 1.增加原因
    • 2.common-log4j2-starter
        • 1.目录结构
        • 2.SkipLogAspect.java 自定义注解
        • 3.LogAspect.java
          • 1.核心改动
        • 2.完整代码
    • 3.common-log4j2-starter-demo
        • 1.目录结构
        • 2.TraceController.java 新增方法,测试跳过日志切面的注解
        • 3.测试

1.增加原因

因为如果参数是一些大对象,比如HttpServletRequest request,在转化为json的时候就会导致OOM,所以选择新增一个注解让用户自己灵活的决定是否添加日志切面

2.common-log4j2-starter

1.目录结构

CleanShot 2025-01-24 at 18.38.16@2x

2.SkipLogAspect.java 自定义注解
package cn.sunxiansheng.log4j2.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Description: 跳过日志切面的注解
 *
 * @Author sun
 * @Create 2025/1/24 18:08
 * @Version 1.0
 */
@Target({ElementType.METHOD, ElementType.TYPE}) // 可以标注在类或方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
public @interface SkipLogAspect {
}
3.LogAspect.java
1.核心改动

CleanShot 2025-01-24 at 18.39.48@2x

2.完整代码
package cn.sunxiansheng.log4j2.aspectj;

import cn.sunxiansheng.log4j2.annotation.SkipLogAspect;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
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.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

/**
 * 日志切面
 *
 * @author sunxiansheng
 */
@Aspect
@Slf4j
public class LogAspect {

    private static final Gson GSON = new GsonBuilder()
            .setPrettyPrinting()
            .disableHtmlEscaping()
            .create();

    private static final String ANSI_RESET = "\u001B[0m";
    private static final String ANSI_CYAN = "\u001B[92m";

    @Pointcut("execution(public * *..controller..*(..)) || " +
            "execution(public * *..service..*(..))")
    public void applicationPackagePointcut() {
        // 切点定义
    }

    @Around("applicationPackagePointcut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取目标类和方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Class<?> targetClass = joinPoint.getTarget().getClass();

        // 检查是否存在 @SkipLogAspect 注解
        if (method.isAnnotationPresent(SkipLogAspect.class) ||
                targetClass.isAnnotationPresent(SkipLogAspect.class)) {
            // 直接执行目标方法,不记录日志
            return joinPoint.proceed();
        }

        // 正常记录日志逻辑
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();
        Object[] args = joinPoint.getArgs();
        String requestParams = GSON.toJson(args);

        log.info("==> 进入方法: {}.{}()", className, methodName);
        log.info("参数:\n" + ANSI_CYAN + "{}" + ANSI_RESET, requestParams);

        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long endTime = System.currentTimeMillis();

        String response = GSON.toJson(result);

        log.info("<== 退出方法: {}.{}() | 耗时: {} ms", className, methodName, endTime - startTime);
        log.info("返回值:\n" + ANSI_CYAN + "{}" + ANSI_RESET, response);

        return result;
    }
}

3.common-log4j2-starter-demo

1.目录结构

CleanShot 2025-01-24 at 18.41.02@2x

2.TraceController.java 新增方法,测试跳过日志切面的注解
/**
 * 测试跳过日志切面的注解
 *
 * @param msg
 * @return
 */
@SkipLogAspect
@RequestMapping("/skipLogAspect")
public String skipLogAspect(String msg) {
    return "skip log aspect";
}
3.测试

CleanShot 2025-01-24 at 18.42.02@2x

CleanShot 2025-01-24 at 18.42.17@2x

CleanShot 2025-01-24 at 18.43.42@2x

CleanShot 2025-01-24 at 18.42.25@2x


http://www.kler.cn/a/535234.html

相关文章:

  • 告别手动操作!用Ansible user模块高效管理 Linux账户
  • 如果$nextTick内部抛出错误,如何处理?
  • AI大模型:DeepSeek
  • 2025蓝桥杯JAVA编程题练习Day2
  • [Python人工智能] 四十九.PyTorch入门 (4)利用基础模块构建神经网络并实现分类预测
  • ES面试题
  • 三格电子-单串口服务器说明
  • [paddle] 矩阵乘法
  • 高性能音频分析仪,音频分析器、国产音频分析仪
  • QUIC协议详解
  • ES6- 代码编程风格(let、字符串、解构赋值)
  • 所遇皆温柔,佛系过生活
  • pycharm集成通义灵码应用
  • 【PyTorch】解决Boolean value of Tensor with more than one value is ambiguous报错
  • leetcode——组合总和(回溯算法详细讲解)
  • DNN(深度神经网络)近似 Lyapunov 函数
  • 解锁反序列化漏洞:从原理到防护的安全指南
  • 【OpenCV插值算法比较】
  • 给排水 笔记
  • MapReduce是什么?
  • Swan 表达式 - 数组相关操作
  • 【Prometheus】如何通过golang生成prometheus格式数据
  • 使用 MMCM 的 I/O 时序 ZHOLD/BUF_IN 补偿
  • Spring Boot 入门 与 无法解析符号 springframework 的解决
  • 71.StackPanel黑白棋盘 WPF例子 C#例子
  • 基于Redis分布式锁