javassist可以对一个已经编译好了的.class文件的字节码进行改动,比如说我可以为一个类添加一个方法,添加一个属性,也可以修改一个方法等,还可以对一个方法,异常进行拦截等。 javassist的最外层的API和JAVA的反射包中的API颇为类似。它使你可以在装入ClassLoder之前,方便的查看类的结构。它主要由CtClass,,CtMethod,,以及CtField几个类组成。 这是网上的一个例子。它修改了Hello类里say方法。 public class Hello { public void say() { System.out.println("hello"); } }
public class Test {
public static void main(String args[]) throws Exception{ ClassPool cp = ClassPool.getDefault(); CtClass cc = cp.get("com.hundsun.ares.liuji.myfirst.Hello"); CtMethod m = cc.getDeclaredMethod("say"); m.setBody("{System.out.println(\"shit\");}"); m.insertBefore("System.out.println(\"fuck\");"); m.insertAfter("System.out.println(\"method over\");"); Class c = cc.toClass(); Hello h = (Hello)c.newInstance(); h.say(); } }
运行结果: fuck shit method over 从结果我们可以看出,hello类里的say()方法已经被修改。 现在我们在来分析各个类的作用 ClassPool类跟踪和控制所操作的类,它读取.class文件。这个类的工作方式与 JVM 类装载器非常相似,但是有一个重要的区别是它不是将装载的、要执行的类作为应用程序的一部分链接,类池使所装载的类可以通过 Javassist API 作为数据使用, CtClass装载到类池中的类,与标准的 Java java.lang.Class类一样,CtClass提供了检查类数据(如字段和方法)的方法。不过,这只是CtClass的部分内容,它还定义了在类中添加新字段、方法和构造函数、以及改变类、父类和接口的方法。奇怪的是,Javassist 没有提供删除一个类中字段、方法或者构造函数的任何方法 字段、方法和构造函数分别由javassist.CtField、javassist.CtMethod和javassist.CtConstructor的实例表示。这些类定义了修改由它们所表示的对象的所有方法的方法,包括方法或者构造函数中的实际字节码内容