字节码增强技术-Javassist

字节码

什么是字节码,在这里就不在赘述了,网上教程很多。Java 为了能让 Java 程序编译一次到处运行,用 Java 编译器将程序对源代码编译生成固定格式的字节码(.class文件)供 JVM 使用,因此理论上来说,只要符合 JVM 规范的字节码文件,就可以在 JVM 上运行,不同的 JVM 类语言(如Scala、Groovy、Kotlin)编译成字节码都可在 JVM 运行,除此之外,如果你对 JVM 的字节码规范非常了解的话,通过自己按照 JVM 规范自己写也是可以的。

那么什么是字节码增强呢?简单理解就是通过某种手段或者技术修改编译好的字节码,让新生成的字节码能满足我们的定制需求,这里说的需求就有很多了,比如常用的 AOP 底层很多就是使用字节码增强来达到切面拦截,再比如微服务中的链路追踪就使用了字节码增强(仅仅只一些 Java 客户端)来进行埋点标记来记录调用链关系的,所以了解字节码增强对一些框架能有更深入对理解,对问题排查有很大对帮助。

上面说的通过某种手段或者技术到底指哪些呢?我们最常用的 Java Proxy 也是一种增强技术,另外常用的还有 ASM,AspectJ,Javassist等常用的技术,其中ASM在指令层次操作字节码的,需要对JVM的指令有一定的了解,同时众多的指令也很难记住,操作比较高;AspectJ扩展了 Java,定义了一些专门的AOP语法,其中 Spring AOP 就使用了 AspectJ;Javassist 是强调源代码层次操作字节码的框架,操作起来很容易入手。

Javassist

使用Javassist需要使用javassist.jar。

优势:

  • 操作简单,容易上手
  • 性能高于反射

缺点:

  • 性能相比 ASM ,会低一些
  • 不支持 continue 和 break 表达式,不支持内部类和匿名类,因此在有些场景是不适合的

Javassist 使用 ClassPool 来操作所有的 Java 类。这个类的工作方式与 JVM 类装载器非常相似,但是有一个重要的区别是它不是将装载的、要执行的类作为应用程序的一部分链接,类池使所装载的类可以通过 Javassist API 作为数据使用。可以使用默认的类池(ClassPool.getDefault()),它是从 JVM 搜索路径中装载的,也可以定义一个搜索您自己的路径列表的类池。甚至可以直接从字节数组或者流中装载二进制类,以及从头开始创建新类。

装载到类池中的类由 CtClass 实例表示。与标准的 Class 类一样, CtClass 提供了检查类数据(如字段和方法)的方法。不过,这只是 CtClass 的部分内容,它还定义了在类中添加新字段、方法和构造函数、以及改变类、父类和接口的方法。

字段、方法和构造函数分别由 CtField、CtMethod 和 CtConstructor 的实例表示。这些类定义了修改由它们所表示的对象的所有方法的方法,包括方法或者构造函数中的实际字节码内容。

Javassist 常用类的说明:

  • CtClass(compile-time class):编译时类信息,它是一个class文件在代码中的抽象表现形式,可以通过一个类的全限定名来获取一个CtClass对象,用来表示这个类文件。
  • ClassPool:ClassPool是一张保存CtClass信息的HashTable,key为类的全限定名称,value为类名对应的CtClass对象。当我们需要对某个类进行修改时,就是通过pool.getCtClass(“className”)方法从pool中获取到相应的CtClass。
  • CtMethod、CtField:这两个比较好理解,对应的是类中的方法和属性,可以用于定义或者修改一些方法和字段。

Javassist 增强的代码片段是使用字符串来编写的,基本和平时写的 Java 源代码一致,主要的不同是一些是以 $ 开头的标识符,用于表示方法或者构造函数参数、方法返回值等。

比如:


public void method1(String arg1, Object arg2) {
    // 增强代码片段
    {
        System.out.println("入参 1: "   $1); // arg1
        System.out.println("入参 2: "   $2); // arg2
    }
}

入门 Demo

通过一个平时经常需要用的业务日志记录来学习,平时业务日志操作记录基本都是通过 AOP 实现的,这次就使用字节码增强技术来进行实现,对业务代码基本无任何侵入。

首先定义一个业务 service

public clas
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值