需求:
假設已經有了一些類,現在想統計每個方法調用花了多長時間,該怎么做?
思路:
我第一個想法就是去每個方法執行前后記錄一下當前的時間戳,然后相減統計到日志。
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起來。
切記項目的版本號要統一,避免沒必要的坑!
