通过注解使用AOP统一打印出入参

1.使用引用

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.创建对应的注解

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface LogFormat {
    /**
     * 是否打印入参 默认打印
     */
    boolean isPrintReqParam() default true;

    /**
     * 是否打印出参 默认打印
     */
    boolean isPrintResParam() default true;
}

3.创建注解的实现类

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Maps;
import com.apaas.commons.annotation.LogFormat;
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 org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class LogFormatAop {
    /**
     * 日志打印切入点
     */
    @Pointcut("@within(com.apaas.commons.annotation.LogFormat) " +
            "|| @annotation(com.apaas.commons.annotation.LogFormat)")
    private void consolePointCut() {
    }

    @Around("consolePointCut()")
    public Object around(ProceedingJoinPoint poiny) throws Throwable {
        // 获取目标的签名信息和方法信息
        MethodSignature signature = (MethodSignature) poiny.getSignature();
        Method method = signature.getMethod();
        // 目标方法名
        String methodName = method.getName();
        // 获取注解数据
        LogFormat logFormat = method.getAnnotation(LogFormat.class);
        // 是否打印入参
        boolean printReqParam = logFormat.isPrintReqParam();
        // 是否打印出参
        boolean printRespParam = logFormat.isPrintResParam();
        if (printReqParam) {
            // 打印入参
            // 获取方法入参
            String[] parameterNames = signature.getParameterNames();
            // 获取参数值
            Object[] parameterValues = poiny.getArgs();
            if (parameterNames != null && parameterNames.length > 0) {
                Map<String, Object> reqParamMap = buildReqParamMap(parameterNames, parameterValues);
                formatConsoleLogReq(methodName, reqParamMap);
            }
        }
        Object resParamMap = poiny.proceed();
        if (printRespParam) {
            // 打印出参
            formatConsoleLogRes(methodName, resParamMap);
        }
        return resParamMap;
    }

    private Map<String, Object> buildReqParamMap(String[] parameterNames, Object[] parameterValues) {
        Map<String, Object> reqParamMap = Maps.newHashMap();
        for (int i = 0; i < parameterNames.length; i++) {
            final Object parameterValue = parameterValues[i];
            // 无效参数跳过
            if (ObjectUtil.hasEmpty(parameterValues[i], parameterNames[i])) {
                continue;
            }
            if (parameterValue instanceof HttpServletRequest) {
                // 提取请求头信息有效信息
                reqParamMap.put("unitId", ((HttpServletRequest) parameterValue).getHeader("UnitId"));
                reqParamMap.put("token", ((HttpServletRequest) parameterValue).getHeader("token"));
            } else {
                // 装入请求体数据
                reqParamMap.put(parameterNames[i], parameterValue);
            }
        }
        return reqParamMap;
    }



    /**
     * 打印出参
     */
    private static void formatConsoleLogRes(String methodName, Object resParamMap) {
        formatConsoleInfoLog(methodName, "请求出参", resParamMap);
    }

    /**
     * 打印入参
     */
    private static void formatConsoleLogReq(String methodName, Object reqParamMap) {
        formatConsoleInfoLog(methodName, "请求入参", reqParamMap);
    }

    /**
     * 格式化打印info日志
     *
     * @param methodName     方法名
     * @param mainMsg        主信息
     * @param param          参数
     */
    public static void formatConsoleInfoLog(String methodName, String mainMsg, Object param) {
        if (ObjectUtil.hasEmpty(methodName, param)) {
            return;
        }
        String paramStr = null;
        if (param instanceof Number) {
            // 数值类型
            paramStr = param.toString();
        } else {
            // pojo
            paramStr = JSONUtil.toJsonStr(param);
        }
        log.info("{} {}:{}", methodName, mainMsg, StrUtil.equals(paramStr, "{}") ? param : paramStr);
    }

}

4.具体运用和使用效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值