springboot-自定义注解实现入参出参打印日志

原理:自定义注解+AOP切面

第1步,新建springboot项目

项目中必须有web依赖

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

第2步,自定义注解

自定义一个WebLog注解,后面会用到controller的方法上

import java.lang.annotation.*;

/**
 * 打印方法入参和出参的注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface WebLog {
    /**
     * 日志描述信息
     *
     * @return
     */
    String description() default "";

}

第3步,为注解配置切面

  1. 使用@WebLog作为切点,这样所有配置了该注解的方法,都能被切面切到。
  2. 使用前置通知doBefore打印入参信息;
  3. 使用环绕通知doAround打印出参信息;
import cn.demo.annotation.WebLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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

@Aspect
@Component
@Slf4j
public class WebLogAspect {

    /**
     * 换行符
     */
    private static final String LINE_SEPARATOR = System.lineSeparator();

    /**
     * 以自定义 @WebLog 注解为切点
     */
    @Pointcut("@annotation(cn.demo.annotation.WebLog)")
    public void webLog() {
    }

    /**
     * 在切点之前织入
     *
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 获取 @WebLog 注解的描述信息
        String methodDescription = getAspectLogDescription(joinPoint);

        // 打印请求相关参数
        log.info("========================================== Start ==========================================");
        // 打印请求 url
        log.info("URL            : {}", request.getRequestURL().toString());
        // 打印描述信息
        log.info("Description    : {}", methodDescription);
        // 打印 Http method
        log.info("HTTP Method    : {}", request.getMethod());
        // 打印调用 controller 的全路径以及执行方法
        log.info("Class Method   : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
        // 打印请求的 IP
        log.info("IP             : {}", request.getRemoteAddr());
        // 打印请求入参
        log.info("Request Args   : {}", joinPoint.getArgs());
    }

    /**
     * 在切点之后织入
     *
     * @throws Throwable
     */
    @After("webLog()")
    public void doAfter() throws Throwable {
        // 接口结束后换行,方便分割查看
        log.info("=========================================== End ===========================================" + LINE_SEPARATOR);
    }

    /**
     * 环绕
     *
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        // 打印出参
        log.info("Response Args  : {}", result);
        // 还可以打印执行耗时
        //log.info("Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
        return result;
    }


    /**
     * 获取切面注解的描述-正确方式
     *
     * @param joinPoint 切点
     * @return 描述信息
     * @throws Exception
     */
    public String getAspectLogDescription(JoinPoint joinPoint)
            throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = null;
        if (!(signature instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        methodSignature = (MethodSignature) signature;
        Method currentMethod =  joinPoint.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        return currentMethod.getAnnotation(WebLog.class).description();
    }
}

第4步,将自定义注解@WebLog加到方法上

  	@WebLog(description = "底库查询")
    @PostMapping("/query")
    public Result<List<Face>> query(@Validated @RequestBody AlbumQueryParam param, BindingResult bindingResult) throws BindException {
        this.validate(bindingResult);
        // 省略逻辑代码
        return null;
 	}

第5步,看打印效果

[INFO ] 2021-01-03 12:54:17.877 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:48] - ========================================== Start ==========================================
[INFO ] 2021-01-03 12:54:17.879 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:50] - URL            : http://localhost:8001/api/album/query
[INFO ] 2021-01-03 12:54:17.879 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:52] - Description    : 底库查询
[INFO ] 2021-01-03 12:54:17.880 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:54] - HTTP Method    : POST
[INFO ] 2021-01-03 12:54:17.881 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:56] - Class Method   : cn.demo.controller.AlbumController.query
[INFO ] 2021-01-03 12:54:17.881 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:58] - IP             : 0:0:0:0:0:0:0:1
[INFO ] 2021-01-03 12:54:17.882 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:60] - Request Args   : AlbumQueryParam(similarity=80.0, albumID=CCL01, topN=10, level=0, feature=7hL3ARQGEu818P797QoS//og9u/sAgX68+8PE/7x/uflEiP0JO/zDfj3+fb85hAJ/eUcCN8TBBcM+gcUCQH+8QIjDQUU8vn9APTn/gMTGBH1BPv45xH5HAT3BQniBO77BgL5AOIRCgDtCgTv/dwO+e8AEP4JA/H5Df398Rn+DgsNCwsB//sPAvby7gv48w8GFyjrEgYaAe328gXxBvbuCvb+BQMRCwkjFgH9/wsA/iD9ARb65AER3gsBD/oAAhXqBP/4EvoRIff78gMWA+v6/hcA6AMC9gP//g0H9/QH/yH0Fg778//78RQk/QkABfn9CgnzGAn5EQ389QUeFP4YCRH8CvT5BwoA4vXs7/4JFvYF++n7ARj8Bv/9D/f6IRIQ/vwEBhnzBfsP9AH9BwELEgP3CPD1//v59w4K/hj5+/f2C/HwCQzsCgLw9BDnBBL+BfkS+vUJBRDtCfL0/PYLD/4GEtsCD/H9/u78BPnz++31AQQJ/u3vBvP9AAz89+vpJlX/wa21hjLTz1eH+pYDn+f9T/HYOrgy98Vn7hURGrQXduMkw2SLJI5H3iCo+hEwaAUvFEPEL6zT1DI20pbbjw==, faceID=CCL0101)
[INFO ] 2021-01-03 12:54:17.902 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:86] - Response Args  : Result(code=200, message=success, result=[Face(deviceID=null, faceID=CCL0101, similarity=100.0, captureTime=null)], duration=5282)
[INFO ] 2021-01-03 12:54:17.903 [http-nio-8001-exec-1] 服务名称:cw-tool-engine-api [cn.demo.aspect.WebLogAspect:71] - =========================================== End ===========================================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值