基于Byte Buddy的探针开发实践

这篇博客介绍了ByteBuddy库,一个基于ASM的Java字节码编辑工具,作为JavaProxy、cglib和Javassist等库的替代选择。ByteBuddy提供了DSL和注解支持,简化了动态类型创建。文中展示了如何引入库并使用核心代码创建代理类,以及其在系统监控和链路追踪中的应用。
摘要由CSDN通过智能技术生成

目录

前言

一、Bety Buddy是什么?

1.Bety Buddy 定义

2.代码生成的其他的库类

3.代码生产代理库类性能指标

二、使用步骤

1.引入库

2.核心代码示例

总结



前言

在研发生产或运维中经常会有系统性能监控或链路追踪的需求,接下来我就详细给大家演示一个基于Byte Buddy库类的探针开发过程

一、Bety Buddy是什么?

       

1.Bety Buddy 定义

Byte Buddy 是基于ASM的一种通过领域特定语言(DSL)和注解的针对 Java 虚拟机的字节码编辑库类。

2.代码生成的其他的库类

Java Proxy

Java 类库自带了一个代理工具,它允许为实现了一系列接口的类创建代理。这个内置的代理供应商非常方便,但局限性也特别明显。 上面提到的安全框架就不能用这样的方式来实现的,因为我们想扩展是类而不是扩展接口。

cglib

代码生成库(注:这里指 cglib)诞生于 Java 初期,但不幸的是没有跟上 Java 平台的发展。然而,cglib 仍然是一个相当强大的库,但其积极的开发却变得相当模糊。鉴于此,其许多用户已经离开了 cglib。

Javassist

该库附带一个编译器,它使用包含 Java 源代码的字符串,这些字符串在应用程序的运行时被转换为 Java 字节码。这是非常有前途的,本质上是一个好主意,因为 Java 源代码显然是描述 Java 类的好方法。但是,Javassist 编译器在功能上比不了 javac 编译器,并且在动态组合字符串以实现比较复杂的逻辑时容易出错。此外,Javassist 还提供了一个类似于 Java 类库中的代理工具,但允许扩展类,并不限于接口。然而,Javassist 的代理工具的范围在其 API 和功能上仍然受到限制。

即使评估完这些框架,但我们相信 Byte Buddy 提供了功能和便利,可以减少徒劳地搜索。Byte Buddy 提供了一种具有表现力的领域特定语言,允许通过编写简单的 Java 代码和使用强大的类型为你自己的代码创建非常自定义的运行时类。与此同时,Byte Buddy 还具有非常开放的定制性,并不限制开箱即用的功能。如果需要,你甚至可以为任何实现的方法定义自定义字节码。但即使不知道什么字节代码是或它如何工作,你可以做很多,而不深入到框架。

3.代码生产代理库类性能指标

 

二、使用步骤

1.引入库

引入Bety Buddy库类依赖:

        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.10.19</version>
        </dependency>

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

 

2.核心代码示例

代码如下:

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        // 这里是自己创建的注解类
        AnnotationDescription classAnnotation = AnnotationDescription.Builder.ofType(RuntimeDefinition.class).build();

        AnnotationDescription someAnnotation = AnnotationDescription.Builder.ofType(RuntimeDefinition.class).build();
        Object obj = new ByteBuddy()
                .subclass(Object.class)
                .annotateType(classAnnotation)
                .method(ElementMatchers.named("toString"))
                .intercept(FixedValue.value("Hello World!"))
                .annotateMethod(someAnnotation)
                .make()
                .load(Main.class.getClassLoader())
                .getLoaded().newInstance();

        String toString = obj.toString();
        System.out.println(toString);
        Annotation[] classAnnotations = obj.getClass().getAnnotations();
        for(Annotation annotation : classAnnotations){
            System.out.println("类上面的注解 " +annotation.annotationType());
        }
        System.out.println(obj.getClass().getCanonicalName());
        Method[] methods = obj.getClass().getMethods();
        for(Method method : methods){
            Annotation[] annotations = method.getDeclaredAnnotations();
            for(Annotation annotation : annotations){
                System.out.println(method.getName() + " 方法上面的注解 " +annotation.annotationType());
            }
        }
    }

该处使用的url网络请求的数据。

Hello World!
类上面的注解 interface com.xxx.xxx.agent.RuntimeDefinition
net.bytebuddy.renamed.java.lang.Object$ByteBuddy$orfS0hyn
toString 方法上面的注解 interface com.xxx.xxx.agent.RuntimeDefinition

 


总结


以上就是今天要讲的内容,本文仅仅简单介绍了Bety Buddy的简单使用方法,而Bety Buddy提供了大量能使我们快速生产字节码的方法,如果你好奇那就去分析SkyWalking的源码吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天秤座的架构师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值