- 官网
- github
- 作用
- 简单使用案例
- 依赖
- 动态生成接口的实现
- 对方法作代理增强
https://www.javassist.org/
githubhttps://github.com/jboss-javassist/javassist
作用简单来说Javassist主要用于操作Java字节码,让我们操作字节码变得简单,可以在JVM加载类文件的时候去修改它。与其他字节码编辑器不同的是Javassist提供了两个级别的API,源代码级和字节码级。如果用户使用源级 API,他们可以在不了解 Java 字节码规范的情况下编辑类文件。
目前自己应用到的场景有如下:
- 动态加载实现接口的实现类
- 动态增强原有类的方法
动态生成接口的实现org.javassist javassist 3.22.0-GA
首先定义一个接口
public interface IHello {
void sayHello(String name, Integer age);
}
动态生成接口实现类并调用
public class Proxy{ private Class t; public Proxy(Class t){ this.t = t; } private static final String PROXYFREFIX = "$Proxy"; private static final String PROXYSUFFIX = "Impl"; public static void main(String[] args) throws Exception{ ClassPool pool = ClassPool.getDefault(); //接口实现类的名字 Proxy proxy = new Proxy<>(IHello.class); String clazzName = proxy.getPackageName() + proxy.getProxyObjectName(); System.out.println("clazzName: " + clazzName); // 创建实现类 = public class com.test.cider.javassist$ProxyIHelloImpl {} CtClass targetClass = pool.makeClass(clazzName); //获得接口的CtClass IHello.class.getName() = proxy.t.getClass().getName() CtClass interf = pool.getCtClass(IHello.class.getName()); CtClass[] interfs = new CtClass[]{interf}; // 这行代码等 = public class ProxyIHelloImpl implements IHello{} targetClass.setInterfaces(interfs); // 获取接口 sayHello 方法 CtMethod method = interf.getDeclaredMethod("sayHello"); // 创建方法 CtMethod m = new CtMethod(method.getReturnType(),method.getName(),method.getParameterTypes(),targetClass); //设置方法的实现类 // System.out.println("姓名: " + $1 + " 年龄: " + $2); m.setBody(" System.out.println("姓名: " + $1 + " 年龄: " + $2);n"); targetClass.addMethod(m); //生成Class文件 // targetClass.writeFile("C:\Users\java\src\main\resources"); //生成Class载入内存 Class> target = targetClass.toClass(); //实例化 IHello o = (IHello) target.getDeclaredConstructor().newInstance(); o.sayHello("weihubeats", 18); } //获取包名 public String getPackageName(){ Package aPackage = t.getPackage(); return aPackage.getName(); } //获取代理对象的名称 public String getProxyObjectName(){ return PROXYFREFIX+t.getSimpleName()+PROXYSUFFIX; } }
实际效果
对方法作代理增强首先写一个需要增强的方法
public class JavassistTest {
public String sayHello(String a) {
System.out.println("原来方法也执行了,参数: " + a);
return "1223";
}
}
然后对原有方法进行增强
public class Test {
public static void sayHello(String aa) {
System.out.println("增强" + aa);
}
public static void main(String[] args) throws Exception{
CtClass cc;
ClassPool pool = ClassPool.getDefault();
cc = pool.get("com.test.cider.javassist.JavassistTest");
CtMethod ctMethod = cc.getDeclaredMethod("sayHello");
ctMethod.insertBefore("com.test.cider.javassist.Test.sayHello($1);");
cc.toClass();
JavassistTest javassistTest = new JavassistTest();
javassistTest.sayHello("haha");
}
}
执行结果



