• Java学习-026-类名或方法名应用之二 -- 统计分析基础


    前文讲述了类名或方法的应用之一调试源码,具体请参阅:Java学习-025-类名或方法名应用之一 -- 调试源码

    此文主要讲述类名或方法应用之二统计分析,通过在各个方法中插桩(调用桩方法),获取方法的调用关系。通过调用关系,我们可以统计出被调用次数比较多的方法,同时也可以构建全系统调用关系链;通过操作重要业务流程,可以统计组成重要业务流程的主要方法,加强相应的单元测试、功能、安全、性能等方面的测试。对于软件产品质量控制存在非凡的意义。

    下面构建的演示示例调用关系如下所示:

    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 源码文件内容如下所示:

    /**
     * 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("
    ");
        }
        
        /**
         * 
         * 
         * @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("
    ");
        }
    }
    

    InvokeClass.java 源码文件内容如下所示:

    /**
     * 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君临天下AppDataLocalTemp	estng-eclipse--1803609229	estng-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 的您一份参考。

    最后,非常感谢亲的驻足,希望此文能对亲有所帮助。热烈欢迎亲一起探讨,共同进步。非常感谢! ^_^

     

  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/fengpingfan/p/4738159.html
Copyright © 2020-2023  润新知