springAOP實現方法運行時間統計


aop的before和after,尋思分別在兩個方法里獲得當前時間,最后一減就可以了。

因此,今天就探討了一下這個問題,和大家分享一下。

創建maven工程,引入spring的依賴包,配置好applicationContext-aop.xml,如下:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
">

<!-- 切面所在的類包路徑 -->
<context:component-scan base-package="com.product" />
<!-- 啟動該切面代理 -->
<!-- <aop:aspectj-autoproxy proxy-target-class="true"/> -->

</beans>

然后,創建兩個包,一個來放切面類,一個放測試類。

測試類如下

package com.product.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service
public class TimeTest {

public void testMethod(){
System.out.println("執行方法");
}

public void testMethod2(){
int sum = 0;
for(int i=0;i<1000;i++){
sum += i;
}
System.out.println(sum);
System.out.println("執行方法2");
}

@SuppressWarnings("resource")
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext-aop.xml");
TimeTest A = (TimeTest)ctx.getBean("timeTest");
A.testMethod();
//A.testMethod2();
ctx.destroy();
}

}

寫這個切面類。

 

package com.product.test.aopTest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MethodTimeMonitor {

private long startTime;

//聲明切面類路徑,類型必須為final String類型的,注解里要使用的變量只能是靜態常量類型的
//public static final String POINT = "execution(* com.product.service.*.*(..))";
//也可以使用注解聲明切入點,如下
@Pointcut("execution(* com.product.service.*.*(..))")
public void point(){}

@Before("point()")
public void doBefore(){
this.startTime = System.currentTimeMillis();
}


@After("point()")
public void doAfter(){
long endTime = System.currentTimeMillis();
System.out.println("方法執行了"+(endTime-this.startTime)+"ms");
}

}
現在,運行測試類,ok,看到如下結果:

 

說明次思路可行。

只是,當面試官繼續問我before和after是寫在兩個方法中,那變量怎么能互通的時候,我竟然忘了它們本來就在一個類里,只需要把起始時間設為成員變量就好了,支吾了半天沒答上來。

之后,筆者看了些資料,發現還有其他思路,比如aroud。

此思路和之前的沒太大改變,只是在MethodTimeMonitor里,注掉之前的方法,新增around方法,如下:

@Around("point()")
public Object doAround(ProceedingJoinPoint pjp){
long startTime = System.currentTimeMillis();
Object obj = null;
try {
obj = pjp.proceed();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endTime = System.currentTimeMillis();

MethodSignature signature = (MethodSignature) pjp.getSignature();
String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
System.out.println(methodName+"方法執行了"+(endTime-startTime)+"ms");
return obj;
}

好了,再次運行測試類,發現還是能得到一樣的結果。

 

此外,筆者還了解到,aspect可以通過配置的方式實現,詳見http://calatustela.iteye.com/blog/1910025。

另外,要提醒大家的是,注意:

1.配置文件盡可能放在src下,引入時直接加classpath就可以了。

2.<context:annotation-config />的作用是為使用到的注解自動配置對應的AnnotationBeanPostProcessor。而當使用自動掃描<context:component-scan 
base-package="com.product.service" />后,它兼具有上述功能,因此兩者取一即可。
此外,注意使用了spring注解的類包都要包括在內,否則可能某些包沒有掃描,出現意外結果。
3.spring的注解bean加載機制中,獲取某個bean用context.getBean("className");不過注意,className是該類首字母小寫后的類名。若要自定義,可在注解后聲明,如
@Controller("Name")。詳見http://blog.csdn.net/damon834274634/article/details/38725909。
---------------------

轉自:https://blog.csdn.net/baidu_41722481/article/details/79379040


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM