天天看點

java進階|基于springAop和自定義注解進行方法的耗時統計

本想着基于aop做些比較實際一點的業務場景,但是伺服器不給力,暫時沒法連接配接上了,額,這也是自己沒有去寫其它内容的客觀原因之一了,因為涉及不了資料庫層面,是以慢慢拖到了現在,也隻有在寫一些代碼層面的内容了,寫完這篇就暫時不寫了,今年還有其它事情要做。

java進階|基于springAop和自定義注解進行方法的耗時統計

首先,引入spring架構提供的aop依賴包。

<!-- 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>           

複制

然後自定義一個注解,用于标注辨別一下,很簡單,生命周期是運作時,作用域在方法上,因為我這裡主要就是統計方法的耗時時間的。

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 {
}
           

複制

然後我們定義一個切面類,用于處理請求時的内容。

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;
    }

}
           

複制

定義一個切面,然後執行環繞通知,進行方法的統計時間,進行日志的輸出列印。

這裡就是最後的示例程式進行模拟了。

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做一下比較有意思的一個場景的内容,内容就到這裡結束了。