java进阶|基于springAop和自定义注解进行方法的耗时统计

2020-04-10 15:13:55 浏览数 (1)

本想着基于aop做些比较实际一点的业务场景,但是服务器不给力,暂时没法连接上了,额,这也是自己没有去写其它内容的客观原因之一了,因为涉及不了数据库层面,所以慢慢拖到了现在,也只有在写一些代码层面的内容了,写完这篇就暂时不写了,今年还有其它事情要做。

首先,引入spring框架提供的aop依赖包。

代码语言:javascript复制
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>

然后自定义一个注解,用于标注标识一下,很简单,生命周期是运行时,作用域在方法上,因为我这里主要就是统计方法的耗时时间的。

代码语言:javascript复制
package com.wpw.springbootjuc.controller;

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

/**
 * 自定义注解,统计方法执行耗时时间
 * wpw
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CountTime {
}

然后我们定义一个切面类,用于处理请求时的内容。

代码语言:javascript复制
package com.wpw.springbootjuc.controller;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 定义一个统计方法执行耗时的切面类
 *
 * @author wpw
 */
@Aspect
@Component//使用spring容器进行管理
@Slf4j
public class CountTimeAspect {
    /**
     * 首先定义一个切点
     */
    @org.aspectj.lang.annotation.Pointcut("@annotation(com.wpw.springbootjuc.controller.CountTime)")
    public void countTime() {
    }

    @Around("countTime()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object obj = null;
        try {
            long beginTime = System.currentTimeMillis();

            obj = joinPoint.proceed();
            //获取方法名称
            String methodName = joinPoint.getSignature().getName();
            //获取类名称
            String className = joinPoint.getSignature().getDeclaringTypeName();
            log.info("类:[{}],方法:[{}]耗时时间为:[{}]", className, methodName, System.currentTimeMillis() - beginTime   "毫秒");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return obj;
    }

}

定义一个切面,然后执行环绕通知,进行方法的统计时间,进行日志的输出打印。

这里就是最后的示例程序进行模拟了。

代码语言:javascript复制
package com.wpw.springbootjuc.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * 统计调用一个方法的耗时时长
 *
 * @author wpw
 */
@RestController
public class CountTimeController {
    @CountTime
    @GetMapping(value = "/time")
    public String helloCount() {
        final Long sleepTime = 6L;
        try {
            TimeUnit.SECONDS.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello countTime";
    }

    @CountTime
    @RequestMapping(value = "/count")
    public String countTime() {
        final int count = 10000;
        for (int i = 0; i < count; i  ) {

        }
        return "hello";
    }
}

以上就是整个基于aop加上自定义注解进行统计方法耗时的过程,简单快速,后面有时间会基于redis做一下比较有意思的一个场景的内容,内容就到这里结束了。

aop

0 人点赞