zoukankan      html  css  js  c++  java
  • 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 的您一份参考。

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

     

  • 相关阅读:
    2021.6.2 Python网络编程
    2021.6.1 数据库
    2021.5.29 PHP大作业
    2021.5.28 bootstrap和vue
    2021.5.27 三个和尚
    2021.5.26 Python操作Mysql数据库
    2021.5.25 PHP作业
    2021.5.24 Python解析XML
    如何用 GPU 训练模型?
    44 内核中的中断处理(上)
  • 原文地址:https://www.cnblogs.com/fengpingfan/p/4738159.html
Copyright © 2011-2022 走看看