示例:
java
public class JavassistTest {
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("meituan.bytecode.javassist.Base");
CtMethod m = cc.getDeclaredMethod("process");
m.insertBefore("{ System.out.println(\"start\"); }");
m.insertAfter("{ System.out.println(\"end\"); }");
Class c = cc.toClass();
Base h = (Base) c.newInstance();
h.process(); // 输出: start process end
}
}
特点:
直接插入 Java 代码字符串,简单高效。
适合快速开发,但性能低于 ASM。
四、运行时类重载问题
问题:
JVM 不允许运行时重载已加载的类(如 toClass() 会抛出错误)。
场景:
在运行的 JVM 中动态增强类(如每 5 秒输出变化)。
示例代码:
java
public class Base {
public static void main(String[] args) {
while (true) {
try {
Thread.sleep(5000L);
process();
} catch (Exception e) {
break;
}
}
}
public static void process() {
System.out.println("process");
}
}
目标:运行时将 process() 增强为 start process end。
五、解决运行时重载
1. Instrument
简介:
JVM 提供的类修改工具,支持运行时插桩(JDK 1.6 起)。
接口:ClassFileTransformer
transform():类加载时调用,可返回新字节码。
示例:
java
public class TestTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) {
if (!className.equals("meituan/bytecode/jvmti/Base")) return classfileBuffer;
try {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("meituan.bytecode.jvmti.Base");
CtMethod m = cc.getDeclaredMethod("process");
m.insertBefore("{ System.out.println(\"start\"); }");
m.insertAfter("{ System.out.println(\"end\"); }");
return cc.toBytecode();
} catch (Exception e) {
e.printStackTrace();
}
return classfileBuffer;
}
}