1. 程式人生 > >java監測方法執行時間/效率方法

java監測方法執行時間/效率方法

前言:

  這周在寫一個小專案,雖然小但是是純調外部介面的,調完了介面還不停的迴圈介面返回的資料(已轉換JSONArray),然後再判斷值,再做不同處理,關鍵是資料量還比較大,這剛做完還沒開始上線,測試也還沒開始測呢,就想著自己先看看每個方法執行效率,省的資料大了專案掛掉(迴圈判斷好多,有時還有2個for巢狀迴圈),就是純粹在時間上進行監測,沒有記憶體和cpu的監控。

  主要利用了Spring AOP 技術,對想要統計的方法進行橫切處理,方法執行前開始計時,方法執行後停止計時,得到計時方法就是該方法本次消耗時間。

步驟:

  • 首先編寫自己的Interceptor類來實現MethodInterceptor類,來用於切入方法,執行計時程式碼
  • Spring AOP 的XML配置,配置需要監測的方法和切入方法(自定義的Interceptor)

java程式碼:

複製程式碼

package com.cplatform.tencent.task;

import java.util.HashMap;
import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.time.StopWatch;
/**
 * 方法執行時間測試
 * @author liuyt
 * @date   2014-11-16 下午3:39:08
 * bolgs   http://www.cnblogs.com/liuyitian/
 */
public class MethodTimeActive implements MethodInterceptor {
    /**
     * 自定義map集合,key:方法名,value:[0:執行次數,1:總時間]
     */
    public static Map<String,Long[]> methodTest = new HashMap<String, Long[]>();
    /**
     * 攔截要執行的方法
     */
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 建立一個計時器
        StopWatch watch = new StopWatch();
        // 計時器開始
        watch.start(); 
        // 執行方法
        Object object = invocation.proceed();
        // 計時器停止
        watch.stop();
        // 方法名稱
        String methodName = invocation.getMethod().getName();
        // 獲取計時器計時時間
        Long time = watch.getTime();
        if(methodTest.containsKey(methodName)) {
            Long[] x = methodTest.get(methodName);
            x[0]++;
            x[1] += time;
        }else{
            methodTest.put(methodName, new Long[] {1L,time});
        }
        return object;
    }
    
}

複製程式碼


XML配置:

複製程式碼

<!-- 日誌記錄某個類中方法花費時間aop -->  
    <aop:config>  
        <!-- Spring 2.0 可以用 AspectJ 的語法定義 Pointcut,這裡自定義要攔截方法的包所在 -->  
        <aop:advisor id="methodTimeLog" advice-ref="methodTimeAdvice" pointcut="execution(* com.cplatform.tencent.sync..*.*(..))"/>  
        <aop:advisor id="methodTimeLog2" advice-ref="methodTimeAdvice" pointcut="execution(* com.cplatform.tencent.utils..*.*(..))"/>  
    </aop:config>  
    <bean id="methodTimeAdvice" class="com.cplatform.tencent.task.MethodTimeActive"/>

複製程式碼

  使用AOP面向切面技術時,XML配置裡面千萬別忽略了以下配置:


TEST:

複製程式碼

package test;

import java.util.Map;
import java.util.Set;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.cplatform.tencent.sync.PersistenceTicketService;
import com.cplatform.tencent.task.MethodTimeActive;
import com.cplatform.tencent.utils.AppConfig;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-configuration/*.xml"})
@ActiveProfiles("production")
public class CopyOfDBTest {
    
    @Autowired
    private AppConfig appConfig;    // 這是我專案裡用到的  可忽略
    @Autowired
    private PersistenceTicketService persistenceTicketService;
    
    // 測試某個方法,這個方法內部呼叫了很多業務處理方法
    @Test
    public void testInsertOrUpdate() {
        persistenceTicketService.insertOrUpdate(appConfig.getTicketCityIds(), appConfig.getAgentId());
    }
    
    // 測試方法執行完畢後,取出定義的Map集合,取出資料
    @After
    public void testMethodActive() {
        Map<String, Long[]> map = MethodTimeActive.methodTest;
        Set<String> set = map.keySet();
        Long[] x = null;
        for(String s : set) {
            x = map.get(s);
            System.out.println(s+":"+x[0]+"次,"+x[1]+"毫秒");
        }
    }
}

複製程式碼

  上面用到的是Spring和junit對WEB方法進行測試,具體可以參照SpringJunit4 進行單元測試


console輸出:


   其實也不難,大家可能也都會,獻下小丑了,歡迎拍磚。

                        寫作不易,難免有疏漏和錯誤,還請慷慨指正,不錯請推薦

   ps:歡迎轉載,轉載請註明出處:http://www.cnblogs.com/liuyitian/p/4101531.html


                                          每天多學一點點     程式碼少敲一點