一、简介
Javassist (JAVA programming ASSISTant) 是在 Java 中编辑字节码的类库;它使 Java 程序能够在运行时定义一个新类, 并在 JVM 加载时修改类文件。
我们常用到的动态特性主要是反射,在运行时查找对象属性、方法,修改作用域,通过方法名称调用方法等。在线的应用不会频繁使用反射,因为反射的性能开销较大。其实还有一种和反射一样强大的特性,但是开销却很低,它就是Javassit。
首先需要引入jar包:
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
二、ClassPool
ClassPool pool = ClassPool.getDefault();
// 根据类路径获取该类的CtClass对象
CtClass cc = pool.get("test.Rectangle");
// 传入一个类路径,创建一个类
CtClass cc = pool.makeClass("com.rickiyang.learn.javassist.Person");
//
cc.setSuperclass(pool.get("test.Point"));
cc.writeFile();
在 Javassist 中,类 表示Javassist.CtClass表示的是class 文件。一个 GtClass (编译时类)对象可以处理一个 class 文件,ClassPool
是 CtClass
对象的容器。它按需读取类文件来构造 CtClass
对象,并且保存 CtClass
对象以便以后使用。
ClassPool
需要关注的方法:
- getDefault : 返回默认的
ClassPool
是单例模式的,一般通过该方法创建我们的ClassPool; - appendClassPath, insertClassPath : 将一个
ClassPath
加到类搜索路径的末尾位置 或 插入到起始位置。通常通过该方法写入额外的类搜索路径,以解决多个类加载器环境中找不到类的尴尬; - toClass : 将修改后的CtClass加载至当前线程的上下文类加载器中,CtClass的
toClass
方法是通过调用本方法实现。需要注意的是一旦调用该方法,则无法继续修改已经被加载的class; - get , getCtClass : 根据类路径名获取该类的CtClass对象,用于后续的编辑。
二、读取和写入字节码
类 Javassist.CtClass 是类文件的抽象表示形式。CtClass (编译时类) 对象是处理类文件的句柄。下面的程序是一个非常简单的示例:
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("test.Rectangle");
cc.setSuperclass(pool.get("test.Point"));
cc.writeFile();