byte buddy字节码增强——输出方法执行时间

news2024/9/25 15:25:13

目标: 输出各函数执行时间

  1. 引包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>bytebuddyTest</artifactId>
    <version>1.0-SNAPSHOT</version>


    <properties>
    </properties>

    <dependencies>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.8.20</version>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy-agent</artifactId>
            <version>1.8.20</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        // maven中指定Premain-Class
                        <manifestEntries>
                            <Premain-Class>buddy.agent.MethodAgent</Premain-Class>
                            <Can-Redefine-Classes>true</Can-Redefine-Classes>
                            <Can-Retransform-Classes>true</Can-Retransform-Classes>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  1. Pre-Main 操作类
package buddy.agent;

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;

import java.lang.instrument.Instrumentation;

public class MethodAgent {

    public static void premain(String args, Instrumentation instrumentation) {

        System.err.println("MethodAgent " + args);

        AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {
            return builder.method(ElementMatchers.any()).intercept(MethodDelegation.to(MethodTimeCheck.class));
        };
        AgentBuilder.Listener listener = new AgentBuilder.Listener() {
            @Override
            public void onDiscovery(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
                System.out.println(s + " onDiscovery");
            }

            @Override
            public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b, DynamicType dynamicType) {
                System.out.println(typeDescription + " onTransformation");
            }

            @Override
            public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule, boolean b) {
                System.out.println(typeDescription + " onIgnored");
            }

            @Override
            public void onError(String s, ClassLoader classLoader, JavaModule javaModule, boolean b, Throwable throwable) {
                throwable.printStackTrace();
            }

            @Override
            public void onComplete(String s, ClassLoader classLoader, JavaModule javaModule, boolean b) {
                System.out.println(s + " onComplete");
            }
        };

        new AgentBuilder
                .Default()
                .type(ElementMatchers.nameStartsWith("buddy.say"))
                .transform(transformer)
                .with(listener)
                .installOn(instrumentation);


    }
}

拦截器处理类

package buddy.agent;

import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

public class MethodTimeCheck {

    @RuntimeType
    public static void interceptor(@Origin Method method, @SuperCall Callable<?> callable) {
        long startTime =System.currentTimeMillis();
        try {
            callable.call();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(method + " cost " + (System.currentTimeMillis() - startTime) + " ms");
        }
    }

}

  1. maven 打包,然后在VM option 中添加 -javaagent:XXX(your path).jar=args
  2. 测试类
package buddy.say;

public class HelloMethod {

    public void say() {
        try {
            Thread.sleep(1000);
            System.out.println("execute OK~");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

package buddy;

import buddy.say.HelloMethod;

public class StartExecute {

    public static void main(String[] args) {
        HelloMethod helloMethod = new HelloMethod();
        helloMethod.say();
    }
}

在这里插入图片描述

结束 ~ ~ (^ v ^)~ ~

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

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

相关文章

Vue Router入门:为Vue.js应用添加导航

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Vue.js新手指南:从零开始建立你的第一个应用

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

在SpringBoot项目中整合SpringSession,基于Redis实现对Session的管理和事件监听

1、SpringSession简介 SpringSession是基于Spring框架的Session管理解决方案。它基于标准的Servlet容器API&#xff0c;提供了Session的分布式管理解决方案&#xff0c;支持把Session存储在多种场景下&#xff0c;比如内存、MongoDB、Redis等&#xff0c;并且能够快速集成到Spr…

C++之operator=与operator==用法区别(二百一十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

宝塔面板日志和缓存占用磁盘空间很大,如何清理?

服务器使用的宝塔面板&#xff0c;最近发现服务器的“系统盘”快爆满了&#xff0c;点面板上日志管理都要收费&#xff0c;我也不是很懂服务器的运维&#xff0c;使用ai进行询问&#xff0c;得到了解决&#xff1a; /var/log 日志目录 运行下面的命令查找是哪些目录占用空间很…

解决vue项目导出当前页Table为Excel

解决vue项目中导出当前页表格为Excel表格的方案 用到的技术&#xff1a; Vue2Element-uifile-saverxlsx 1、创建vue项目&#xff0c;安装element-ui 2、创建一个组件&#xff0c;组件内放入表格&#xff0c;和导出按钮 <template><div><!-- 导出的按钮 -->…

阿里云交互式建模(PAI-DSW)训练并微调推理ChatGLM模型

参考内容为《轻量微调和推理ChatGLM模型实践》 点击“交互式建模&#xff08;DSW&#xff09;”&#xff0c;然后选择“创建实例” 写上实例名称&#xff0c;然后选择GPU规格&#xff0c;选择“ecs.gn6v-c8g1.2xlarge(8 vCPU&#xff0c;32GB)” 页面往下拉选择“pytorch:…

嵌入式-数据进制之间的转换

目录 一.简介 1.1十进制 1.2二进制 1.3八进制 1.4十六进制 二.进制转换 2.1二进制-十进制转换 2.2八进制-十进制转换 2.3十六进制-十进制转换 2.4十进制-二进制转换 2.5十进制-八进制转换 2.6十进制-十六进制转换 2.7小数部分转换 一.简介 被传入到计算机的数据要…

在macOS使用VMware踩过的坑

目录 MAC提示将对您的电脑造成伤害/MAC OS 升级到10.15.3后vmware虚拟机黑屏 mac系统下&#xff0c;vm虚拟机提示打不开/dev/vmmon mac VMware Workstation 在此主机上不支持嵌套虚拟化 mac VMware清理虚拟机空间 VMware Fusion 13在M2芯片的Mac上安装 Windows 11 首先需…

Android 12.0 SystemUI下拉状态栏定制化之隐藏下拉通知栏布局功能实现(二)

1.前言 在12.0的系统定制化开发中,由于从12.0开始SystemUI下拉状态栏和11.0的变化比较大,所以可以说需要从新分析相关的SystemUI的 布局,然后做分析来实现不同的功能,今天就开始实现关于隐藏SystemUI下拉状态栏中的通知栏布局系列二,去掉下拉状态栏中 通知栏部分 白色的…

LomBok常用注解及详细介绍

LomBok常用注解及详细介绍 前言 Lombok是一个作用于编辑器和构建工具的 Java 库&#xff0c;可以对编写的 Java 代码进行增强&#xff0c;比如说不用再写实体类的 getter 方法&#xff0c;equals 方法而是自动生成&#xff0c;自动生成日志输出变量等等&#xff0c;减少重复模…

C++ PrimerPlus 复习 第六章 分支语句和逻辑运算符

第一章 命令编译链接文件 make文件 第二章 进入c 第三章 处理数据 第四章 复合类型 &#xff08;上&#xff09; 第四章 复合类型 &#xff08;下&#xff09; 第五章 循环和关系表达式 第六章 分支语句和逻辑运算符 第六章 分支语句和逻辑运算符 if语句&#xff1b;逻辑…

笔记1.1 计算机网络基本概念

计算机网络是通信技术与计算机技术紧密结合的产物 通信系统模型&#xff1a; 计算机网络是一种通信网络 计算机网络是互连的、自洽的计算机集合。 互连&#xff1a;互联互通 自洽&#xff1a;无主从关系 通过交换网络互连主机 Internet&#xff1a;数以百万计的互连的计算设…

SpringCLoud——Nacos配置中心

Nacos实现配置管理 统一配置管理 配置更新热更新 统一配置的创建是在UI界面中完成的&#xff1a; 首先我们点击【配置管理】然后点击【配置列表】&#xff1a; 然后我们就看到了配置管理界面&#xff0c;但是此时这里是空的&#xff0c;我们可以创建一些配置文件&#xff1a…

(21)多线程实例应用:双色球(6红+1蓝)

一、需求 1.双色球: 投注号码由6个红色球号码和1个蓝色球号码组成。 2.红色球号码从01--33中选择,红色球不能重复。 3.蓝色球号码从01--16中选择。 4.最终结果7个号码&#xff1a;61&#xff1b;即33选6(红) 16选1(蓝) 5.产品: …

【MySQL索引学习】MySQL索引详细学习

一、什么是索引 索引是一种用于快速查询和检索数据的数据结构。 可以将其类比于书的目录。 索引底层的数据结构存在很多种类型&#xff0c;常见的索引结构有: B 树&#xff0c; B树 和 Hash、红黑树。在 MySQL 中&#xff0c;无论是 Innodb 还是 MyIsam&#xff0c;都使用了 …

如何在 Nginx 中隐藏版本号

文章目录 修改nginx.conf文件修改fastcgi.conf文件参考文档 修改nginx.conf文件 打开 Nginx 配置文件&#xff0c;一般在 /etc/nginx/nginx.conf 或 /usr/local/nginx/conf/nginx.conf。在 http 块中添加以下内容&#xff1a;server_tokens off;修改fastcgi.conf文件 编辑php…

kafka 消费者的消费策略以及再平衡1

一kafka 再平衡 1.1 kafka的再平衡 Kafka的再平衡是consumer所消费的topic发生变化时&#xff0c;topic上的分区再次分配的情况。 默认策略是 Range CooperativeSticky 。 Kafka 可以同时使用 多个分区分配策略。 1.2 kafka触发再平衡的情况 1.consumer group中的新增或删…

Windows系统webp图片预览插件

由于工作中经常需要对组图查看和管理&#xff0c;而Windows 7系统不支持在文件夹下直接预览webp图片。经过查找&#xff0c;发现 WebP Codec for Windows 扩展插件不错&#xff0c;完美地解决webp图片预览问题。 目录 1、webp文件浏览插件 2、下载插件并安装 3、浏览webp图片…

vue项目部署,出现两个ip的原因

我宁愿靠自己的力量打开我的前途,而不愿求有力者的垂青。——雨果 tags: 篇首语&#xff1a;本文由小常识网(cha138.com)小编为大家整理&#xff0c;主要介绍了vue项目部署&#xff0c;出现两个ip的原因相关的知识&#xff0c;希望对你有一定的参考价值。 参考技术A 在部署v…