【Javassist】快速入门系列02 使用Javassist实现方法执行时间统计

news2024/11/26 8:52:47

系列文章目录

01 在方法体的开头或结尾插入代码
02 使用Javassist实现方法执行时间统计

前言

上一章我们介绍了使用Javassist实现一个简单的Hello World程序,学会了Javassist创建类和新增方法。本章主要介绍如何使用Javassist实现一个无侵入的方法执行时间统计

引入Javassist jar包

在上一篇文章已经创建了一个maven工程并引入了javassist的jar包,如果你是第一次观看本系列文章,也可以复制以下maven依赖将jar包导入工程。

        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.28.0-GA</version>
        </dependency>

使用Javassist实现方法执行时间统计

/**
 * 【Javassist】快速入门系列02 使用Javassist实现方法执行时间统计
 * 公众号&B站:精致的王同学
 * @author 精致的王同学
 * @date 2022/12/19 17:23
 */
public class Basic02ExecTime {
    public static void main(String[] args) throws Exception{
        // 获取javassist的类池
        ClassPool pool = ClassPool.getDefault();
        // 获取basic.StockService javassist的ctClass文件
        CtClass ctClass = pool.get("basic.StockService");
        // 获取声明的queryStockNum方法
        CtMethod method = ctClass.getDeclaredMethod("queryStockNum");
        // 为StockService类新增stime和etime字段
        CtField stime = new CtField(CtClass.longType, "stime", ctClass);
        CtField etime = new CtField(CtClass.longType, "etime", ctClass);
        ctClass.addField(stime);
        ctClass.addField(etime);
        // 在方法体之前插入代码
        method.insertBefore("stime = System.currentTimeMillis();");
        // 在方法体之后插入代码
        method.insertAfter("etime = System.currentTimeMillis();\n" +
                "System.out.println(\"执行时长:\"+(etime - stime)+\"毫秒\");");
        // 将类写成文件
        ctClass.writeFile();
        // 获取生成后的类文件
        Class<?> clazz = ctClass.toClass();
        // 创建新的实例
        Object obj = clazz.newInstance();
        // 获取生成后的queryStockNum方法
        Method queryStockNum = clazz.getDeclaredMethod("queryStockNum", Long.class);
        // 调用生成后的queryStockNum方法
        queryStockNum.invoke(obj,(Object) 1l);
    }
}

以上Basic02ExecTime类创建了一个main方法,该方法中首先获取javassist的类池pool,然后调用pool.get(“basic.StockService”)方法获取到basic包下的StockService类。StockService类源码如下:

/**
 * 库存业务类
 * 公众号&B站:精致的王同学
 * @author 精致的王同学
 * @date 2022/12/19 17:23
 */
public class StockService {
    public Integer queryStockNum(Long skuId) throws Exception {
        // 调用库存数量接口
        Random random = new Random();
        Long mills = Long.valueOf(random.nextInt(5)*1000);
        // 模拟接口调用耗时
        Thread.sleep(mills);
        return 0;
    }
}

该类主要模拟获取sku库存数量的逻辑。使用Thread.sleep(mills)模拟接口调用耗时。

回到BasicExecTime 的main方法中,在获取到basic.StockService的ctClass对象后,获得了其声明的queryStockNum方法的CtMethod对象。

然后通过调用new CtField(CtClass type, String name, CtClass declaring) 为StockService类声明了两个字段。其中CtField构造方法的第一个参数代表字段的类型,第二个参数代表字段名称,最后一个参数代表新增字段的CtClass对象。

声明这两个字段的原因是Javassist不允许在插入的代码块中方法方法的局部变量。

之后便是调用 method.insertBefore(“stime = System.currentTimeMillis();”); 方法在方法体前插入获取当前时间毫秒数的代码,并将其赋给变量stime 。insertBefore方法的参数为字符串类型的代码块。

最后调用 method.insertAfter(“etime = System.currentTimeMillis();\n” +
“System.out.println(“执行时长:”+(etime - stime)+“毫秒”);”);方法在方法体之后插入代码,将方法执行的时间打印在屏幕上。

剩下的代码为模拟调用javassist修改后的queryStockNum方法。输出结果为:
queryStockNum方法输出结果

总结

本篇文章介绍了使用Javassist实现方法执行时间统计,同时学习了使用Javassist在方法体的开头/结尾插入代码和为类添加字段。Javassist可以在无侵入的前提下在方法体前后加入内容,非常的方便。

说明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/101818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DCN神州数码——DHCP相关操作指令(超详细)

DHCP服务器配置 service dhcp 启动DHCP 服务器或中继功能 ip dhcp pool pool1 network-address 1.1.1.1 24 default-router dns-server 8.8.8.8 domain-name dcn.com netbios-name-server 2.2.2.2 lease 5 ip dhcp excluded-address 2.2.2.2 创建DHCP地址池pool1配置地…

PHP反序列化详解(一)——反序列化基础

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是PHP反序列化详解&#xff08;一&#xff09;——反序列化基础。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#x…

西藏旅行网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; (1)旅游线路信息发布以及预定功能&#xff1a;顾客可通网站查看相应的旅游线路信息 和预定旅游线路功能&#xff0c;管理…

OpenCV(8)-OpenCV中的形态学

OpenCV中的形态学 形态学概述 什么是形态学处理&#xff1a; 基于图像形态进行处理的一些基本方法 这些处理方法基本上是对二进制图像进行处理卷积核决定这图像处理后的效果基本方法&#xff1a; 腐蚀与膨胀开运算闭运算顶帽黑帽 图像二值化 将图像的每个像素变成两种值&a…

服务器设置tomcat开机自启动(cmd命令行语句)

1 找到tomcat安装目录&#xff0c;进入bin/文件夹下面&#xff0c;在此打开windows 命令行窗口。 2 输入 service install tomcatXXX将tomcat注册成为windows服务&#xff0c;其中tomcatXXX为服务名。 3查看刚刚注册的服务 “我的电脑”-》右键管理 发现刚刚的服务是手动的&…

DevOps-6:Jenkins使用技巧

1、如何提升Jenkins的Job并行构建数 默认情况下&#xff0c;Jenkins只配置了2个Executor&#xff0c;即只允许最多2个Job同时构建&#xff0c;这个值可以修改&#xff1a; 在Manage Jenkins>Configure System里&#xff0c;找到 # of executors&#xff0c;修改这个值就好&…

DW学生美食网页设计作业——餐饮美食汉堡企业网站6页面带轮播(HTML+CSS+JavaScript)

&#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计&#x1f469;‍&#x1f393;,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等&#xff0c;用的最多的还是DW&#xff0c;当然不同软件写出的…

cython混淆加密

python代码是一种解释型的语言&#xff0c;有了代码和环境就可以执行&#xff0c;它无需编译。如果需要对代码进行混淆&#xff0c;可以借助cython这个库。它的安装很简单&#xff0c;直接运行pip install cython就可以安装。 进行代码混淆之前&#xff0c;还需要一个环境&…

windows下编译libevent源码

《Linux下编译libevent源码》讲述了linux下编译libevent源码的方法&#xff0c;本文讲述其在windows平台的编译。 一、下载libevent源码 https://libevent.org/ 下载libevent源码并解压。 二.安装依赖项 下载安装OpenSSL。https://slproweb.com/products/Win32OpenSSL.html 三…

MySQL8.0高级篇(下)-事务与日志和备份

文章目录一、事务基础知识1、数据库事务概述1.1 基本概念1.2 事物的ACID特性1.3 事务的状态2、如何使用事务2.1 显式事务2.2 隐式事务2.3 隐式提交数据的情况2.4 使用举例3、事务隔离级别3.1 数据准备3.2 数据并发问题3.3 SQL中的四种隔离级别3.4 MySQL支持的四种隔离级别4、事…

【实时数仓】DWM层订单宽表之需求分析、订单和订单明细关联源码

文章目录一 DWM层-订单宽表1 需求分析与思路2 订单和订单明细关联代码实现&#xff08;1&#xff09;从Kafka的dwd层接收订单和订单明细数据a 创建订单实体类b 创建订单明细实体类c 在dwm包下创建OrderWideApp读取订单和订单明细数据d 测试&#xff08;2&#xff09;订单和订单…

SpringBoot中的starter:whywhatmake

1、为什么用starter 我们知道&#xff0c;springboot框架是为了简化spring框架开发推出的&#xff0c;那么&#xff0c;在之前的spring框架开发中&#xff0c;如果我们需要连接数据库&#xff0c;引入mybatis框架&#xff0c;需要怎么操作呢&#xff1f;我们需要去maven仓库找…

当 chatGPT 被职场 PUA ,笑麻了

大家最近是不是被 chatGPT 刷屏了&#xff1f;简单来说&#xff0c;chatGPT 是一个智能聊天引擎。 那 chatGPT 和小爱同学、 siri 有什么区别呢&#xff1f; 如果体验过的朋友&#xff0c;能感受到区别还是很大&#xff0c;chatGPT 的智能表现过于优秀&#xff0c;远远超过了这…

深入浅出DPDK KNI核心技术

一、KNI KNI全称&#xff1a;Kernel NIC Interface&#xff0c;内核网卡接口&#xff0c;允许用户态程序访问linux控制平面。 在DPDK报文处理中&#xff0c;有些报文需要发送到内核协议栈进行处理&#xff0c;如GTP-C控制报文 如果报文数量较少&#xff0c;可以使用内核提供…

Lua热更新

Lua热更新解决方案 文章目录Lua热更新解决方案1.AB包1.1 AB包概述1. 从0开始的Lua语法1.1 HelloWorld1.2 数据类型1.3 字符串1.4 运算符1.5 条件语句1.6 循环语句1.7 函数1.8 数组1.9 迭代器1.10 字典&#xff0c;类&#xff0c;对象1.11 多脚本执行1.12 特殊语法1.13 协程1.14…

hive时间和字符串互转,时间函数

hive里经常需要将字符串转化为date或timestamp 或者转化为日期格式的string 先说一个简单的 cast(xx as date/string/timestamp) 这个大多情况都可以用 1.to_date to_date只保留年月日,参数必须是string类型的yyyy-MM-dd HH:mm:ss或者date或timestamp类型,返回值是date类型,…

尚太科技开启招股:预计募资总额22亿元,业绩增长迅猛

12月19日&#xff0c;石家庄尚太科技股份有限公司&#xff08;下称“尚太科技”&#xff0c;SZ:001301&#xff09;开启招股&#xff0c;将在深圳证券交易所主板上市。本次冲刺上市&#xff0c;尚太科技的发行价格为33.88元/股&#xff0c;发行数量为6494.37万股&#xff0c;募…

MySQL Binlog温故知新

目录 一、什么是Binlog 二、Binlog文件记录模式 三、Binlog 日志内容 四、常用的binlog日志操作命令 五、binlog日志中间件 一、什么是Binlog Binlog &#xff08;Binary log&#xff09;是MySQL的二进制日志&#xff0c;以二进制的形式记录了对于数据库的变更&#xff0…

Tesseract-OCR 和cnocr/cnstd

Tesseract-OCR学习系列 Tesseract-OCR学习系列&#xff08;四&#xff09;API - 简书 参考文档&#xff1a;https://github.com/tesseract-ocr/tesseract/wiki/APIExample 这篇文章介绍了GetComponentImages等基础api的用法 Python 自动识别图片文字—保姆级OCR实战教程 Py…

使用界面配置静态路由(保姆级教程)

啰嗦几句 因为写的很详细&#xff0c;保姆级别的&#xff0c;所以看起来内容很多&#xff0c;但是东西就那一点&#xff0c;你自己配个2、3遍就会了。期末考试也不用担心这个实验了。 使用Cisco Packet Tracer这个软件。 原文件下载 补充&#xff1a;下载后使用Cisco Packet T…