利用Spring AOP記錄方法的執(zhí)行時(shí)間
一、前言
對于spring aop這個(gè)我就不多介紹了,網(wǎng)上一搜一大把,使用過spring的人都知道spring的ioc和aop。ioc我們常用,但在我們自己的系統(tǒng)中,aop的使用幾乎為零,除了這個(gè)監(jiān)控的小功能應(yīng)用到了,其他的基本上沒有使用到。下面小編就給大家整理下利用Spring AOP記錄方法執(zhí)行時(shí)間的解決方案,有需要的一起看看吧。
二、解決方案
1、傳統(tǒng)方法
最簡單、粗暴的方法是給各個(gè)需要統(tǒng)計(jì)的方法開始和結(jié)尾處加的時(shí)間戳,然后差值計(jì)算結(jié)果即可,代碼如下:
long startTime = System.currentTimeMillis();
// 業(yè)務(wù)代碼
long endTime = System.currentTimeMillis();
System.out.println("程序運(yùn)行時(shí)間:" + (endTime - startTime) + "ms"); //輸出程序運(yùn)行時(shí)間
這樣的方式需要給很多統(tǒng)計(jì)方法都加上耗時(shí)時(shí)間的代碼,這些代碼與核心業(yè)務(wù)無關(guān)卻大量重復(fù)、分散在各處,維護(hù)起來也困難。
2、面向切面編程的方法
所以,不推薦使用上面壞味道的代碼。想了很久,打算利用Spring AOP的思想來完成這個(gè)功能,話不多說代碼和相關(guān)的解釋如下:
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;
/**
* 檢測方法執(zhí)行耗時(shí)的spring切面類
* 使用@Aspect注解的類,Spring將會(huì)把它當(dāng)作一個(gè)特殊的Bean(一個(gè)切面),也就是不對這個(gè)類本身進(jìn)行動(dòng)態(tài)代理
* @author blinkfox
* @date 2016-07-04
*/
@Aspect
@Component
public class TimeInterceptor {
private static Log logger = LogFactory.getLog(TimeInterceptor.class);
// 一分鐘,即1000ms
private static final long ONE_MINUTE = 1000;
// service層的統(tǒng)計(jì)耗時(shí)切面,類型必須為final String類型的,注解里要使用的變量只能是靜態(tài)常量類型的
public static final String POINT = "execution (* com.blinkfox.test.service.impl.*.*(..))";
/**
* 統(tǒng)計(jì)方法執(zhí)行耗時(shí)Around環(huán)繞通知
* @param joinPoint
* @return
*/
@Around(POINT)
public Object timeAround(ProceedingJoinPoint joinPoint) {
// 定義返回對象、得到方法需要的參數(shù)
Object obj = null;
Object[] args = joinPoint.getArgs();
long startTime = System.currentTimeMillis();
try {
obj = joinPoint.proceed(args);
} catch (Throwable e) {
logger.error("統(tǒng)計(jì)某方法執(zhí)行耗時(shí)環(huán)繞通知出錯(cuò)", e);
}
// 獲取執(zhí)行的方法名
long endTime = System.currentTimeMillis();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
// 打印耗時(shí)的信息
this.printExecTime(methodName, startTime, endTime);
return obj;
}
/**
* 打印方法執(zhí)行耗時(shí)的信息,如果超過了一定的時(shí)間,才打印
* @param methodName
* @param startTime
* @param endTime
*/
private void printExecTime(String methodName, long startTime, long endTime) {
long diffTime = endTime - startTime;
if (diffTime > ONE_MINUTE) {
logger.warn("-----" + methodName + " 方法執(zhí)行耗時(shí):" + diffTime + " ms");
}
}
}
注意:最后還需要在applicationContext.xml文件中加上AOP需要的配置<aop:aspectj-autoproxy/>,這樣Spring才能識別到它。
總結(jié)
以上就是關(guān)于利用Spring AOP記錄方法執(zhí)行時(shí)間的全部內(nèi)容,希望這篇文章的內(nèi)容對大家的學(xué)習(xí)或者工作帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
Java實(shí)現(xiàn)冪等性校驗(yàn)的示例代碼
我們在做web應(yīng)用的時(shí)候通常會(huì)遇到前端提交按鈕重復(fù)點(diǎn)擊的場景,在某些新增操作上就需要做冪等性限制來保證數(shù)據(jù)的可靠性,所以本文主要介紹了如何使用java?aop實(shí)現(xiàn)冪等性校驗(yàn),需要的可以參考下2024-02-02
java實(shí)現(xiàn)圖片轉(zhuǎn)base64字符串 java實(shí)現(xiàn)base64字符串轉(zhuǎn)圖片
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)圖片轉(zhuǎn)base64字符串,java實(shí)現(xiàn)base64字符串轉(zhuǎn)圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
Spring擴(kuò)展點(diǎn)之BeanFactoryPostProcessor詳解
這篇文章主要介紹了Spring擴(kuò)展點(diǎn)之BeanFactoryPostProcessor詳解,Spring的設(shè)計(jì)非常優(yōu)雅,有很多的擴(kuò)展點(diǎn)供我們對項(xiàng)目進(jìn)行擴(kuò)展,今天學(xué)習(xí)一下Spring其中擴(kuò)展點(diǎn)之一的BeanFactoryPostProcessor,需要的朋友可以參考下2023-11-11
Kotlin中?StateFlow?或?SharedFlow?的區(qū)別解析
Kotlin協(xié)程中的StateFlow和SharedFlow是響應(yīng)式數(shù)據(jù)流,分別用于UI狀態(tài)管理和事件通知,StateFlow有初始值,只保留最新值,適用于UI狀態(tài)管理;SharedFlow沒有初始值,可以配置緩存大小,適用于事件通知,感興趣的朋友一起看看吧2025-03-03

