一、前言
對于spring aop這個我就不多介紹了,網(wǎng)上一搜一大把,使用過spring的人都知道spring的ioc和aop。ioc我們常用,但在我們自己的系統(tǒng)中,aop的使用幾乎為零,除了這個監(jiān)控的小功能應(yīng)用到了,其他的基本上沒有使用到。下面小編就給大家整理下利用Spring AOP記錄方法執(zhí)行時間的解決方案,有需要的一起看看吧。
二、解決方案
1、傳統(tǒng)方法
最簡單、粗暴的方法是給各個需要統(tǒng)計的方法開始和結(jié)尾處加的時間戳,然后差值計算結(jié)果即可,代碼如下:
1
2
3
4
5
6
|
long startTime = System.currentTimeMillis(); // 業(yè)務(wù)代碼 long endTime = System.currentTimeMillis(); System.out.println( "程序運(yùn)行時間:" + (endTime - startTime) + "ms" ); //輸出程序運(yùn)行時間 |
這樣的方式需要給很多統(tǒng)計方法都加上耗時時間的代碼,這些代碼與核心業(yè)務(wù)無關(guān)卻大量重復(fù)、分散在各處,維護(hù)起來也困難。
2、面向切面編程的方法
所以,不推薦使用上面壞味道的代碼。想了很久,打算利用Spring AOP的思想來完成這個功能,話不多說代碼和相關(guān)的解釋如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
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í)行耗時的spring切面類 * 使用@Aspect注解的類,Spring將會把它當(dāng)作一個特殊的Bean(一個切面),也就是不對這個類本身進(jìn)行動態(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)計耗時切面,類型必須為final String類型的,注解里要使用的變量只能是靜態(tài)常量類型的 public static final String POINT = "execution (* com.blinkfox.test.service.impl.*.*(..))" ; /** * 統(tǒng)計方法執(zhí)行耗時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)計某方法執(zhí)行耗時環(huán)繞通知出錯" , e); } // 獲取執(zhí)行的方法名 long endTime = System.currentTimeMillis(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); String methodName = signature.getDeclaringTypeName() + "." + signature.getName(); // 打印耗時的信息 this .printExecTime(methodName, startTime, endTime); return obj; } /** * 打印方法執(zhí)行耗時的信息,如果超過了一定的時間,才打印 * @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í)行耗時:" + diffTime + " ms" ); } } } |
注意:最后還需要在applicationContext.xml
文件中加上AOP需要的配置<aop:aspectj-autoproxy/>
,這樣Spring才能識別到它。
總結(jié)
以上就是關(guān)于利用Spring AOP記錄方法執(zhí)行時間的全部內(nèi)容,希望這篇文章的內(nèi)容對大家的學(xué)習(xí)或者工作帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。