需求:
假设已经有了一些类,现在想统计每个方法调用花了多长时间,该怎么做?
思路:
我第一个想法就是去每个方法执行前后记录一下当前的时间戳,然后相减统计到日志。
OK,没问题,那么这样做合理吗?
首先,工作量大且全部都是重复劳动;
其次,扩招性极其差;
再次,不优雅,写代码不仅要考虑到完成需求,一定要以最优雅的形式完成。
所以决定采用spring的面向切面编程技术来辅助完成这项功能。
步骤:
一、首先新建一个ApiMonitor.java:
@Aspect public class ApiMonitor { @Pointcut("execution(* com.spring.service.*.*(..))") private void pointCutMethod() { } //声明前置通知 @Before("pointCutMethod()") public void doBefore() { System.out.println("前置通知"); } //声明后置通知 @AfterReturning(pointcut = "pointCutMethod()", returning = "result") public void doAfterReturning(String result) { System.out.println("后置通知"); System.out.println("---" + result + "---"); } //声明例外通知 @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e") public void doAfterThrowing(Exception e) { System.out.println("例外通知"); System.out.println(e.getMessage()); } //声明最终通知 @After("pointCutMethod()") public void doAfter() { System.out.println("最终通知"); } //声明环绕通知 @Around("pointCutMethod()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入方法---环绕通知"); Object o = pjp.proceed(); System.out.println("退出方法---环绕通知"); return o; } }
这段代码是copy的,因为觉得写得很典型。
对于本文的需求,应该采用环绕通知@Around这个注解去完成,只要在pjp.proceed()前后分别调用system.currenttimemillis(),然后相减,就OK了。
另外需要注意的是:excution表达式的语法很容易出错,具体如下
二、在applicationcontext.xml中配置aop相关条目
<bean class"org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
<bean id="aspectBean" class="com.spring.aop.ApiMonitor" />
这样就完成了在spring中的IOC装配。
三、别忘了引入aop的依赖
好吧这个应该放在第一点的,没关系,只要在pom.xml中加入:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.0.5.RELEASE</version> </dependency>
版本根据你项目使用的spring版本而定,不要随便写一个版本,容易出错,我是踩过坑的,因为4.x版本中比3.x版本多了一些类,因此如果是4.x的aop去调3.x的spring可能会发生类找不到的问题,直接导致项目无法run起来。
切记项目的版本号要统一,避免没必要的坑!