前文講述了類名或方法的應用之一調試源碼,具體請參閱:Java學習-025-類名或方法名應用之一 -- 調試源碼html
此文主要講述類名或方法應用之二統計分析,經過在各個方法中插樁(調用樁方法),獲取方法的調用關係。經過調用關係,咱們能夠統計出被調用次數比較多的方法,同時也能夠構建全系統調用關係鏈;經過操做重要業務流程,能夠統計組成重要業務流程的主要方法,增強相應的單元測試、功能、安全、性能等方面的測試。對於軟件產品質量控制存在非凡的意義。java
下面構建的演示示例調用關係以下所示:數據庫
GetClassMethodName.test_invoke_cus_Exception() | |--> InvokeClass.invoke_cus_Exception() | |--> InvokeClass.invokeMethod_001() GetClassMethodName.test_invoke_cus_thread() | |--> InvokeClass.invoke_cus_thread() | |--> InvokeClass.invokeMethod_002() | | | |--> InvokeClass.invokeMethod_003() | | | |--> InvokeClass.getInvokeClass() | |--> InvokeClass.getInvokeClass() | |--> InvokeClass.invoke_cus_Exception() | |--> InvokeClass.invokeMethod_001()
源碼比較簡單,也比較容易理解,直接上碼了,敬請各位小主參閱。如有不足之處,敬請大神指正,不勝感激!安全
GetClassMethodName.java 源碼文件內容以下所示:eclipse
/** * Aaron.ffp Inc. * Copyright (c) 2004-2015 All Rights Reserved. */ package com.java.demo; import org.testng.annotations.Test; /** * Get information of class and method * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo GetClassMethodName.java, 2015-8-13 10:58:39 Exp $ */ public class GetClassMethodName extends InvokeClass{ /** * * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo GetClassMethodName.java test_invoke_cus_Exception, 2015-8-15 10:14:08 Exp $ * */ @Test public void test_invoke_cus_Exception(){ System.out.println(" ====== Main Invoke Method : GetClassMethodName.test_invoke_cus_Exception() =========================== "); this.invoke_cus_Exception(); System.out.println("\n"); } /** * * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo GetClassMethodName.java test_invoke_cus_thread, 2015-8-15 10:13:25 Exp $ * */ @Test public void test_invoke_cus_thread(){ System.out.println(" ====== Main Invoke Method : GetClassMethodName.test_invoke_cus_thread() =========================== "); this.invoke_cus_thread(); System.out.println("\n"); } }
InvokeClass.java 源碼文件內容以下所示:post
/** * Aaron.ffp Inc. * Copyright (c) 2004-2015 All Rights Reserved. */ package com.java.demo; /** * Invoked class * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java, 2015-8-14 01:15:12 Exp $ */ public class InvokeClass extends HelperReporter{ /** * * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java invoke_cus_thread, 2015-8-15 10:14:37 Exp $ * */ public void invoke_cus_thread(){ this.setSte(Thread.currentThread().getStackTrace(), false); System.out.println(this.getInvokeInfoCFML()); this.invokeMethod_002(); this.getInvokeClass(); this.invoke_cus_Exception(); } /** * * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java invoke_cus_Exception, 2015-8-15 10:14:55 Exp $ * */ public void invoke_cus_Exception(){ this.setSte(new Exception().getStackTrace(), true); System.out.println(this.getInvokeInfoCFML()); this.invokeMethod_001(); } /** * By Exception * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java invokeMethod_001, 2015-8-14 01:15:51 Exp $ * */ public void invokeMethod_001(){ StackTraceElement[] ste = new Exception().getStackTrace(); this.setSte(ste, true); System.out.println(this.getInvokeInfoCFML()); } /** * By Thread * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java invokeMethod_002, 2015-8-14 01:16:19 Exp $ * */ public void invokeMethod_002(){ StackTraceElement[] ste = Thread.currentThread().getStackTrace(); this.setSte(ste, false); System.out.println(this.getInvokeInfoCFML()); this.invokeMethod_003(); } /** * Invoke other method which belong to the other class * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java invokeMethod_003, 2015-8-15 10:16:19 Exp $ * */ public void invokeMethod_003(){ StackTraceElement[] ste = Thread.currentThread().getStackTrace(); this.setSte(ste, false); System.out.println(this.getInvokeInfoCFML()); this.getInvokeClass(); } /** * Invoked method * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo InvokeClass.java getInvokeClass, 2015-8-15 10:19:19 Exp $ * */ public void getInvokeClass(){ StackTraceElement[] ste = Thread.currentThread().getStackTrace(); this.setSte(ste, false); System.out.println(this.getInvokeInfoCFML()); } }
HelperReporter.java 源碼文件內容以下所示:性能
/** * Aaron.ffp Inc. * Copyright (c) 2004-2015 All Rights Reserved. */ package com.java.demo; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import org.testng.log4testng.Logger; /** * * @author Aaron.ffp * @version V1.0.0: Jsoup com.demo HelperReporter.java, 2015年8月13日 下午2:52:23 Exp $ */ public class HelperReporter { private Logger logger = Logger.getLogger(this.getClass()); private StackTraceElement[] ste; // store the type of StackTraceElement. true Exception, false Thread private boolean eot = true; public void setSte(StackTraceElement[] ste, boolean eot){ this.ste = ste; this.eot = eot; } /** * Get string about invoke info, * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo HelperReporter.java getInvokeInfoCFML, 2015-8-16 9:20:11 Exp $ * * @return String */ public String getInvokeInfoCFML(){ String invokeInfoCFML = ""; try { Thread.sleep(5); } catch (InterruptedException e) { logger.error("", e); } String current_time = (new SimpleDateFormat("yyyyMMdd-HHmmss-SSS")).format(new Date()); ArrayList<String> icp = this.getInvokeChildParent(); invokeInfoCFML = "[" + current_time + "] " + icp.get(0) + "|" + icp.get(1) + "|" + icp.get(2) + "|" + icp.get(3) + "| invoked by |" + icp.get(4) + "|" + icp.get(5) + "|" + icp.get(6) + "|" + icp.get(7); return invokeInfoCFML; } /** * Get information of invoke relation by StackTraceElement[] which caused by new Exception().getStackTrace() or Thread.currentThread().getStackTrace() * It will be return ArrayList which contains (package|filename|method name|line number) of invoked method and invoke method. * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo HelperReporter.java getInvokeChildParent, 2015-8-16 9:15:05 Exp $ * * @return ArrayList<String> */ public ArrayList<String> getInvokeChildParent(){ ArrayList<String> invokeChildParent = new ArrayList<String>(); // add invoked method info invokeChildParent.add(0, this.eot ? this.ste[0].getClassName() : this.ste[1].getClassName()); invokeChildParent.add(1, this.eot ? this.ste[0].getFileName() : this.ste[1].getFileName()); invokeChildParent.add(2, this.eot ? this.ste[0].getMethodName() : this.ste[1].getMethodName()); invokeChildParent.add(3, "" + (this.eot ? this.ste[0].getLineNumber() : this.ste[1].getLineNumber())); // add invoke method info invokeChildParent.add(4, this.eot ? this.ste[1].getClassName() : this.ste[2].getClassName()); invokeChildParent.add(5, this.eot ? this.ste[1].getFileName() : this.ste[2].getFileName()); invokeChildParent.add(6, this.eot ? this.ste[1].getMethodName() : this.ste[2].getMethodName()); invokeChildParent.add(7, "" + (this.eot ? this.ste[1].getLineNumber() : this.ste[2].getLineNumber())); return invokeChildParent; } /** * Get information of invoke relation by new Exception().getStackTrace(). * It will be return ArrayList which contains (package|filename|method name|line number) of invoked method and invoke method. * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo HelperReporter.java getInvokeChildParentByException, 2015-8-14 13:15:05 Exp $ * * @param ste : new Exception().getStackTrace() * * @return ArrayList<String> */ public ArrayList<String> getInvokeChildParentByException(StackTraceElement[] ste){ ArrayList<String> invokeChildParent = new ArrayList<String>(); // add invoked method info invokeChildParent.add(0, ste[0].getClassName()); invokeChildParent.add(1, ste[0].getFileName()); invokeChildParent.add(2, ste[0].getMethodName()); invokeChildParent.add(3, "" + ste[0].getLineNumber()); // add invoke method info invokeChildParent.add(4, ste[1].getClassName()); invokeChildParent.add(5, ste[1].getFileName()); invokeChildParent.add(6, ste[1].getMethodName()); invokeChildParent.add(7, "" + ste[1].getLineNumber()); return invokeChildParent; } /** * Get information of invoke relation by Thread.currentThread().getStackTrace(). * It will be return ArrayList which contains (package|filename|method name|line number) of invoked method and invoke method. * * @author Aaron.ffp * @version V1.0.0: Jsoup com.java.demo HelperReporter.java getInvokeChildParentByThread, 2015-8-14 13:17:44 Exp $ * * @param ste : Thread.currentThread().getStackTrace() * * @return ArrayList<String> */ public ArrayList<String> getInvokeChildParentByThread(StackTraceElement[] ste){ ArrayList<String> invokeChildParent = new ArrayList<String>(); // add invoked method info invokeChildParent.add(0, ste[1].getClassName()); invokeChildParent.add(1, ste[1].getFileName()); invokeChildParent.add(2, ste[1].getMethodName()); invokeChildParent.add(3, "" + ste[1].getLineNumber()); // add invoke method info invokeChildParent.add(4, ste[2].getClassName()); invokeChildParent.add(5, ste[2].getFileName()); invokeChildParent.add(6, ste[2].getMethodName()); invokeChildParent.add(7, "" + ste[2].getLineNumber()); return invokeChildParent; } }
以 TestNG 執行 GetClassMethodName.java 文件,輸出結果以下所示:單元測試
[TestNG] Running: C:\Users\君臨天下\AppData\Local\Temp\testng-eclipse--1803609229\testng-customsuite.xml ====== Main Invoke Method : GetClassMethodName.test_invoke_cus_Exception() =========================== [20150817-235837-968] com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_Exception|41| invoked by |com.java.demo.GetClassMethodName|GetClassMethodName.java|test_invoke_cus_Exception|27 [20150817-235837-974] com.java.demo.InvokeClass|InvokeClass.java|invokeMethod_001|56| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_Exception|45 ====== Main Invoke Method : GetClassMethodName.test_invoke_cus_thread() =========================== [20150817-235837-983] com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_thread|22| invoked by |com.java.demo.GetClassMethodName|GetClassMethodName.java|test_invoke_cus_thread|43 [20150817-235837-988] com.java.demo.InvokeClass|InvokeClass.java|invokeMethod_002|71| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_thread|26 [20150817-235837-993] com.java.demo.InvokeClass|InvokeClass.java|invokeMethod_003|88| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invokeMethod_002|77 [20150817-235837-998] com.java.demo.InvokeClass|InvokeClass.java|getInvokeClass|105| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invokeMethod_003|94 [20150817-235838-003] com.java.demo.InvokeClass|InvokeClass.java|getInvokeClass|105| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_thread|28 [20150817-235838-008] com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_Exception|41| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_thread|30 [20150817-235838-013] com.java.demo.InvokeClass|InvokeClass.java|invokeMethod_001|56| invoked by |com.java.demo.InvokeClass|InvokeClass.java|invoke_cus_Exception|45 PASSED: test_invoke_cus_Exception PASSED: test_invoke_cus_thread =============================================== Default test Tests run: 2, Failures: 0, Skips: 0 =============================================== =============================================== Default suite Total tests run: 2, Failures: 0, Skips: 0 =============================================== [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 1 ms [TestNG] Time taken by org.testng.reporters.EmailableReporter2@626b2d4a: 24 ms [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@cac736f: 35 ms [TestNG] Time taken by org.testng.reporters.jq.Main@726f3b58: 259 ms [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@aec6354: 522 ms [TestNG] Time taken by org.testng.reporters.XMLReporter@1ee0005: 28 ms
從結果輸出能夠看出,調用關係同初始設置的調用關係圖譜。咱們能夠將上述日誌保存至數據庫,而後進行數據分析,從而得出咱們須要的數據。相信這對各位小主來講不是難事。學習
對於構建全系統調用關係鏈,只是繪製相應的圖表有些困難,後續研究一下,敬請期待!測試
至此, Java學習-026-類名或方法名應用之二 -- 統計分析 順利完結,但願此文可以給初學 Java 的您一份參考。
最後,很是感謝親的駐足,但願此文能對親有所幫助。熱烈歡迎親一塊兒探討,共同進步。很是感謝! ^_^