一、前言
对于spring aop这个我就不多介绍了,网上一搜一大把,使用过spring的人都知道spring的ioc和aop。ioc我们常用,但在我们自己的系统中,aop的使用几乎为零,除了这个监控的小功能应用到了,其他的基本上没有使用到。下面小编就给大家整理下利用Spring AOP记录方法执行时间的解决方案,有需要的一起看看吧。
二、解决方案
1、传统方法
最简单、粗暴的方法是给各个需要统计的方法开始和结尾处加的时间戳,然后差值计算结果即可,代码如下:
1
2
3
4
5
6
|
long startTime = System.currentTimeMillis(); // 业务代码 long endTime = System.currentTimeMillis(); System.out.println( "程序运行时间:" + (endTime - startTime) + "ms" ); //输出程序运行时间 |
这样的方式需要给很多统计方法都加上耗时时间的代码,这些代码与核心业务无关却大量重复、分散在各处,维护起来也困难。
2、面向切面编程的方法
所以,不推荐使用上面坏味道的代码。想了很久,打算利用Spring AOP的思想来完成这个功能,话不多说代码和相关的解释如下:
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; /** * 检测方法执行耗时的spring切面类 * 使用@Aspect注解的类,Spring将会把它当作一个特殊的Bean(一个切面),也就是不对这个类本身进行动态代理 * @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层的统计耗时切面,类型必须为final String类型的,注解里要使用的变量只能是静态常量类型的 public static final String POINT = "execution (* com.blinkfox.test.service.impl.*.*(..))" ; /** * 统计方法执行耗时Around环绕通知 * @param joinPoint * @return */ @Around (POINT) 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 > ONE_MINUTE) { logger.warn( "-----" + methodName + " 方法执行耗时:" + diffTime + " ms" ); } } } |
注意:最后还需要在applicationContext.xml
文件中加上AOP需要的配置<aop:aspectj-autoproxy/>
,这样Spring才能识别到它。
总结
以上就是关于利用Spring AOP记录方法执行时间的全部内容,希望这篇文章的内容对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。