自定义注解实现日志切面打印

562 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情 >>

自定义注解实现日志切面打印

前言

在开发过程中我们不可避免的与日志打交道,那怎么打印日志呢?使用切面全部打印日志打印的太多了 ,那能不能定义一个注解,我们可以录入需要打印的文本呢?本文将带来自定义注解,当需要打印日志时添加此注解即可。

使用技术:

  • 自定义注解
  • spring AOP切面
  • log4g日志包

步骤

1.自定义注解

我们自定义一个注解,名为@LOG,里面添加两个参数,可以传递具体参数进行打印,更灵活。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
    //模块名称
    String model();

    //方法名称
    String method();

}

2.自定义切面

/**
 * 环绕通知:打印耗时,参数,返回信息
 * @author: 
 * @date: 2022-4-26
 **/
@Around("@annotation(com.wanbang.wanbangcarserver.config.annotation.Log)")
Object doAround(ProceedingJoinPoint point) throws Throwable {

    // 获取类名和方法名
    String className = point.getSignature().getDeclaringTypeName();
    String methodName = point.getSignature().getName();


    // 获取方法参数
    MethodSignature signature = (MethodSignature) point.getSignature();
    String[] argKeys = signature.getParameterNames();
    Object[] argValues = point.getArgs();

    Log a = signature.getMethod().getAnnotation(Log.class);
    String method = a.method();
    String model = a.model();

    Map<String, Object> maps = new HashMap<>();
    for (int i = 0; i < argKeys.length; i++) {
        Object arg = argValues[i];
        maps.put(argKeys[i], arg);
    }
    Object result;
    try {
        long startTime = System.currentTimeMillis();
        log.info("【{}-{}】==>请求参数: {}", model, method, maps);
        result = point.proceed(point.getArgs());
        long endTime = System.currentTimeMillis();
        log.info("【{}-{}】==>返回参数: {} ,耗时:{} ms", model, method, JSONObject.toJSONString(result), endTime - startTime);
        return result;
    } catch (Exception e) {
        log.error("【{}-{}】==>返回异常: {}", model, method, e);
        throw  e;
    }
}

做一个环绕切面,切到自己注解的位置@annotation(com.wanbang.wanbangcarserver.config.annotation.Log这样当在方法上添加@LOG注解后就会自动进入这个切面方法。@log方法传的参数分别是model(模块名)method(方法名),由于是环绕切面我们可以计算一下耗时,将耗时也打印出来。

3.具体注解使用方法:

在需要打印日志的方法上加上注解,就可以进行日志打印了。

@Log(method = "存储所有汽车品牌",model = "汽车品牌")

其中model是这个方法所在的模块,method是这个方法的名称,方法做什么的。