package com.packtpub.aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
/**
* 檢測方法執行耗時的spring切面類
* 使用@Aspect注解的類,Spring将會把它當作一個特殊的Bean(一個切面),也就是不對這個類本身進行動态代理
*
* @date 2019-03-29
*/
@Aspect
@Component
public class MethodExecuteTimeViewer {
// service層的統計耗時切面,類型必須為final String類型的,注解裡要使用的變量隻能是靜态常量類型的
public static final String POINT = "execution (* com.packtpub.*.*.*(..))";
private static final long TWO_MILLISECONDS = 2;
private static Log logger = LogFactory.getLog(MethodExecuteTimeViewer.class);
/**
* 統計方法執行耗時Around環繞通知
*
* @param joinPoint
* @return
*/
@Around(POINT)
//等價于@Around("execution (* com.packtpub.restapp.*.*(..))";)
public Object timeAround(ProceedingJoinPoint joinPoint) {
// 定義傳回對象、得到方法需要的參數
Object obj = null;
Object[] args = joinPoint.getArgs();
long startTime = System.currentTimeMillis();
try {
obj = joinPoint.proceed(args);
} catch (Throwable e) {
logger.error("統計某方法執行耗時環繞通知出錯", e);
}
// 擷取執行的方法名
long endTime = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
// 列印耗時的資訊
this.printExecTime(methodName, startTime, endTime);
return obj;
}
/**
* 列印方法執行耗時的資訊,如果超過了一定的時間,才列印
*
* @param methodName
* @param startTime
* @param endTime
*/
private void printExecTime(String methodName, long startTime, long endTime) {
long diffTime = endTime - startTime;
if (diffTime > TWO_MILLISECONDS) {
logger.info("-----" + methodName + " 方法執行耗時:" + diffTime + " ms");
}
}
}
執行
curl http://localhost:8080/user/100
或打開網頁 http://http?/localhost:8080/user/100
調用相關的方法,輸出了相應的執行時間.
https://github.com/HappyFreeAngel/Spring-AOP-MethodExecuteTimeViewer.git