项目中需要统计某些方法的执行时间,最简易的方式是方法执行前记录时间戳startTime,在方法结束前,用时间戳endTime-startTime得出该方法耗时。
但是为了避免无代码侵入并实现通用,于是定义一个注解,如果要统计哪个方法,只需在方法上写上注解即可,通过注解可以获取到方法的参数、方法名、返回值等等信息。
下面是一个简单的时间统计实现:
1.定义一个注解TimeConsume
该注解有一个默认的value属性,value值为方法名或自定义的描述1
2
3
4
5
6
7 ({ElementType.METHOD})
(RetentionPolicy.RUNTIME)
public TimeConsume {
String value() default "方法";
}
2.使用Aspect定义该注解的切面TimeConsumeAspect
定义好注解后,需要对该注解使用的类进行监听,利用Spring框架Aspect实现切面,定义环绕通知,获取到方法的参数、方法名等信息,便于统计所需。对执行方法进行异常捕获,在finally
代码块中实现时间统计逻辑,避免方法异常无法统计。代码如下: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 4j
public class TimeConsumeAspect {
/**
* 切点定义为注解@annotation(注解类路径)
*/
"@annotation(com.weiller.demo.common.annotation.TimeConsume)") (
public void consume(){
}
"consume()") (
public <T> T around(ProceedingJoinPoint pjp) throws Throwable {
Long startTime = System.currentTimeMillis();
Object[] args = pjp.getArgs();
T result;
Method methodClass;
try {
result = (T)pjp.proceed(args);//执行方法
}finally {
long endTime = System.currentTimeMillis();
Signature signature = pjp.getSignature();
String methodName = signature.getName();
Class<?> targetClass = pjp.getTarget().getClass();
Class[] parameterTypes = ((MethodSignature) pjp.getSignature()).getParameterTypes();
methodClass = targetClass.getMethod(methodName, parameterTypes);
Annotation[] annotations = methodClass.getAnnotations();
for (Annotation annotation : annotations){
Class<? extends Annotation> aClass = annotation.annotationType();
String simpleName = aClass.getSimpleName();
if("TimeConsume".equals(simpleName)){
TimeConsume timeConsume = (TimeConsume) annotation;
String value = timeConsume.value();
log.info(value+"[{}] 执行耗时:{}ms",methodName,endTime-startTime);
break;
}
}
}
return result;
}
}
3.测试目标方法中使用
1 |
|