Javassist强调源代码层次操作字节码的框架。
利用Javassist实现字节码增强时,可以无须关注字节码的结构,其优点在于编简单。直接使用Java编程的形式,而不需要了解虚拟机指令,就能动态改变类的结构或者动态生成的类。
其中最重要的是ClassPool、CtClass、CtMethod、CtField这四个类:
CtClass:编译时类信息,它是一个class文件在代码中的抽象表现形式,可以通过一个类的全限定名来获取一个CtClass对象,用来表示这个类文件。
ClassPool:ClassPool是一张保存CtClass信息的HashTable,key为类名,value为类名对应的CtClass对象。当需要对某个类进行修改时,就是通过pool.getCtClass("className")方法从pool中获取到相应的CtClass。
CtMethod、CtField:对应的是类中的方法和属性。
package com.study.demo.bytecode.javassist;
public class HelloWorld {
public void sayHello(){
System.out.println("Hello,World!");
}
}
实例代码:
import org.apache.ibatis.javassist.ClassPool;
import org.apache.ibatis.javassist.CtClass;
import org.apache.ibatis.javassist.CtMethod;
public class JavassistTest {
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("com.study.demo.bytecode.javassist.HelloWorld");
CtMethod m = cc.getDeclaredMethod("sayHello");
m.insertBefore("{ System.out.println(\"start\"); }");
m.insertAfter("{ System.out.println(\"end\"); }");
Class c = cc.toClass();
HelloWorld h = (HelloWorld)c.newInstance();
h.sayHello();
}
}
输出结果:
start
Hello,World!
end
Process finished with exit code 0