SpringBoot利用自定义注解+AOP统计接口执行时间以及打印日志

  1. Maven依赖: 
        <!--引入AOP依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

    2.  自定义注解:

import java.lang.annotation.*;

/**
 * 统计耗时
 */
@Documented //用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化.Documented是一个标记注解,没有成员.
@Target(ElementType.METHOD) //指定被修饰的Annotation可以放置的位置(被修饰的目标)类,方法,属性
@Retention(RetentionPolicy.RUNTIME) //定义注解的保留策略, RetentionPolicy.RUNTIME:注解会在class字节码文件中存在,在运行时可以通过反射获取到
public @interface TakeTime {

    String methodName() default "";
}

    3. TakeTimeAspect(使用AOP技术统计方法执行前后消耗时间): 

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
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.util.Date;

/**
 * 耗时统计
 */
@Slf4j
@Aspect
@Component
public class TakeTimeAspect {
    //统计请求的处理时间
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    ThreadLocal<Long> endTime = new ThreadLocal<>();

    /**
     * 带有@TakeTime注解的方法
     */
//    @Pointcut("within(com.lwx.backend.user.controller.*)")
//    @Pointcut("execution(* com.lwx.backend.user.controller.*.*(..))")
    @Pointcut("@annotation(com.lwx.common.annotation.TakeTime)")
    public void TakeTime() {

    }

    //    @Before("within(com.lwx.backend.user.controller.*)")
    @Before("TakeTime()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 获取方法的名称
        String methodName = joinPoint.getSignature().getName();
        // 获取方法入参
        Object[] param = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        for (Object o : param) {
            sb.append(o + ";");
        }
        log.info("进入《{}》 方法,参数为: {}", methodName,sb.toString());

        System.out.println("System.currentTimeMillis(): "+System.currentTimeMillis());
        System.out.println("new Date(): "+new Date());
        startTime.set(System.currentTimeMillis());
        log.info("方法开始时间:" +startTime.get());
        //接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //记录请求的内容
        log.info("请求URL:" + request.getRequestURL().toString());
        log.info("请求METHOD:" + request.getMethod());
    }

    //    @AfterReturning(returning = "ret", pointcut = "within(com.lwx.backend.user.controller.*)")
    @AfterReturning(returning = "ret", pointcut = "TakeTime()")
    public void doAfterReturning(Object ret) {
        //处理完请求后,返回内容
        log.info("方法返回值:" + JSON.toJSONString(ret));
        endTime.set(System.currentTimeMillis());
        log.info("方法结束时间" +endTime.get());
        log.info("方法结束时间" +new Date());
        log.info("方法执行时间:" + (endTime.get() - startTime.get()));
    }
}

   4. 在接口方法上加上注解

    //根据条件查询数据,并分页
    @TakeTime(methodName = "queryUserList")
    @PostMapping("/queryUserList")             //userMap里的k,v是 pageNum,pageSize,userName,userAge...
    public ResultData<PageInfo<User>> queryUserList(@RequestBody Map<String,Object> userMap) {
        Integer pageNum = Integer.valueOf(StringUtils.isEmpty((String) userMap.get("pageNum")) ? "1" : (String) userMap.get("pageNum"));
        Integer pageSize = Integer.valueOf(StringUtils.isEmpty((String) userMap.get("pageSize")) ? "10" : (String) userMap.get("pageSize"));
        //利用JSON把userMap里的user属性提取出来并转换为user对象
        User user = JSON.parseObject(JSON.toJSONString(userMap),User.class);
        PageHelper.startPage(pageNum, pageSize);
        List<User> userList = userService.getUserList(user);
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        return ResultData.succes(pageInfo);
    }

   5. 打印查看接口耗时:

2022-07-30 22:40:47.057  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 进入《queryUserList》 方法,参数为: {pageNum=1, pageSize=10, userName=张三};
System.currentTimeMillis(): 1659192047058
new Date(): Sat Jul 30 22:40:47 CST 2022
2022-07-30 22:40:47.058  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 方法开始时间:1659192047058
2022-07-30 22:40:47.059  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 请求URL:http://localhost:8080/user/queryUserList
2022-07-30 22:40:47.059  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 请求METHOD:POST
com.lwx.common.aspect.TakeTimeAspect     : 方法返回值:{"data":{"endRow":1,"hasNextPage":false,"hasPreviousPage":false,"isFirstPage":true,"isLastPage":true,"list":[{"comment":"男","userAddress":"广东","userAge":20,"userBirth":1640966400000,"userId":1,"userName":"张三","userSex":"男"}],"navigateFirstPage":1,"navigateLastPage":1,"navigatePages":8,"navigatepageNums":[1],"nextPage":0,"pageNum":1,"pageSize":10,"pages":1,"prePage":0,"size":1,"startRow":1,"total":1},"message":"success","status":100,"timestamp":1659192047819}
2022-07-30 22:40:47.846  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 方法结束时间1659192047846
2022-07-30 22:40:47.846  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 方法结束时间Sat Jul 30 22:40:47 CST 2022
2022-07-30 22:40:47.846  INFO 16276 --- [nio-8080-exec-2] com.lwx.common.aspect.TakeTimeAspect     : 方法执行时间:788

   6. 如果接口引用的注解失效可能是配置注解的类是在别的包下面,需要在启动类上设置扫描注解类的包。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值