一、简介

Javassist (JAVA programming ASSISTant) 是在 Java 中编辑字节码的类库;它使 Java 程序能够在运行时定义一个新类, 并在 JVM 加载时修改类文件。
我们常用到的动态特性主要是反射,在运行时查找对象属性、方法,修改作用域,通过方法名称调用方法等。在线的应用不会频繁使用反射,因为反射的性能开销较大。其实还有一种和反射一样强大的特性,但是开销却很低,它就是Javassit。

首先需要引入jar包:

  1. <dependency>
  2. <groupId>org.javassist</groupId>
  3. <artifactId>javassist</artifactId>
  4. <version>3.25.0-GA</version>
  5. </dependency>

二、ClassPool

  1. ClassPool pool = ClassPool.getDefault();
  2. // 根据类路径获取该类的CtClass对象
  3. CtClass cc = pool.get("test.Rectangle");
  4. // 传入一个类路径,创建一个类
  5. CtClass cc = pool.makeClass("com.rickiyang.learn.javassist.Person");
  6. //
  7. cc.setSuperclass(pool.get("test.Point"));
  8. cc.writeFile();

在 Javassist 中,类 表示Javassist.CtClass表示的是class 文件。一个 GtClass (编译时类)对象可以处理一个 class 文件,ClassPoolCtClass 对象的容器。它按需读取类文件来构造 CtClass 对象,并且保存 CtClass 对象以便以后使用。

ClassPool需要关注的方法:

  1. getDefault : 返回默认的ClassPool 是单例模式的,一般通过该方法创建我们的ClassPool;
  2. appendClassPath, insertClassPath : 将一个ClassPath加到类搜索路径的末尾位置 或 插入到起始位置。通常通过该方法写入额外的类搜索路径,以解决多个类加载器环境中找不到类的尴尬;
  3. toClass : 将修改后的CtClass加载至当前线程的上下文类加载器中,CtClass的toClass方法是通过调用本方法实现。需要注意的是一旦调用该方法,则无法继续修改已经被加载的class
  4. get , getCtClass : 根据类路径名获取该类的CtClass对象,用于后续的编辑。

编写创建对象的类:

二、读取和写入字节码

类 Javassist.CtClass 是类文件的抽象表示形式。CtClass (编译时类) 对象是处理类文件的句柄。下面的程序是一个非常简单的示例:

  1. ClassPool pool = ClassPool.getDefault();
  2. CtClass cc = pool.get("test.Rectangle");
  3. cc.setSuperclass(pool.get("test.Point"));
  4. cc.writeFile();