清一色
2025-04-23
点 赞
0
热 度
61
评 论
0

AOP封装一个记录耗时的注解

代码实现

  • 那现在我们来从头编写一个TakeTimeAspect类,该类通过AOP的方式来监控方法的执行时间,并且记录相关的日志信息。首先导入AOP的依赖

  • 代码实现

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class TakeTimeAspect {

    // ThreadLocal变量用于存储开始时间和结束时间
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    ThreadLocal<Long> endTime = new ThreadLocal<>();

    // 定义一个切入点,匹配带有@TakeTimeLog注解的方法
    @Pointcut("@annotation(com.aimc.paperreduction.common.annotation.TakeTimeLog)")
    public void TakeTime() {}

    // 前置增强方法,在方法执行前记录开始时间
    @Before("TakeTime()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 获得注解
        TakeTimeLog timeLog = getAnnotationLog(joinPoint);
        if (timeLog == null) {
            return;
        }

        startTime.set(System.currentTimeMillis());
    }

    // 返回后增强方法,在方法执行后记录结束时间和执行时间,并记录日志
    @AfterReturning(returning = "ret", pointcut = "TakeTime()")
    public void doAfterReturning(JoinPoint joinPoint, Object ret) {
        Map<String, Object> resultMap = new HashMap<>();
        String[] names = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        if (names.length > 0) {
            for (int i = 0; i < names.length; i++) {
                if (!(joinPoint.getArgs()[i] instanceof HttpServletRequest)) {
                    resultMap.put(names[i], joinPoint.getArgs()[i]);
                }
            }
        }
        // 处理完请求后,返回内容
        log.info("Return:" + JSON.toJSONString(ret));
        endTime.set(System.currentTimeMillis());
        log.info("Execution Time:" + (endTime.get() - startTime.get()));
    }

    // 用于获取方法上的注解
    private TakeTimeLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(TakeTimeLog.class);
        }
        return null;
    }
}
  • ThreadLocal<Long> startTimeThreadLocal<Long> endTime:这两个是ThreadLocal变量,用于存储方法执行的开始时间和结束时间,用于计算方法的执行时间。ThreadLocal允许存储每个线程特定的数据,确保线程安全性。

  • 切点表达式:@Pointcut("@annotation(com.aimc.paperreduction.common.annotation.TakeTimeLog)"),匹配带有@TakeTimeLog注解的方法。

  • 增强方法

    1. @Before("TakeTime()"):在匹配TakeTime切入点的方法之前执行。它捕获方法执行开始的时间,当然这里也可以获取更多的信息,例如方法参数之类的信息都可以拿到,这里我们根据自身项目的需求来编写。

    2. @AfterReturning(returning = "ret", pointcut = "TakeTime()"):这是一个返回后增强方法。它捕获方法的结束时间,记录返回值,并计算并记录执行时间。

  • getAnnotationLog:这是一个私有方法,用于从目标方法中获取TakeTimeLog注解(如果存在)。

使用方式

  • 我们在需要记录耗时的方法上加上此注解即可

@TakeTimeLog
public Wrapper<UploadPaperDTO> uploadDoc(MultipartFile file) throws IOException {
    /**
     *  你的代码逻辑
     */
}


大道至简,知易行难

清一色

isfp 探险家

站长

具有版权性

请您在转载、复制时注明本文 作者、链接及内容来源信息。 若涉及转载第三方内容,还需一同注明。

具有时效性
切换评论

目录

八月寻英,扬帆起航,追风逐梦!!!

39 文章数
7 分类数
2 评论数
14标签数

热门文章

访问统计