Javassist实现类方法修改比ASM简单多了,我们只需要调用CtMethod类的对应的API就可以了。CtMethod提供了类方法修改的API,如:setModifiers可修改类的访问修饰符,insertBeforeinsertAfter能够实现在类方法执行的前后插入任意的Java代码片段,setBody可以修改整个方法的代码等。

    Javassist修改类方法示例代码:**

    1. package com.anbai.sec.bytecode.javassist;
    2. import javassist.ClassPool;
    3. import javassist.CtClass;
    4. import javassist.CtMethod;
    5. import javassist.Modifier;
    6. import org.javaweb.utils.FileUtils;
    7. import java.io.File;
    8. public class JavassistClassModifyTest {
    9. public static void main(String[] args) {
    10. // 创建ClassPool对象
    11. ClassPool classPool = ClassPool.getDefault();
    12. try {
    13. CtClass ctClass = classPool.get("com.anbai.sec.bytecode.TestHelloWorld");
    14. // 获取hello方法
    15. CtMethod helloMethod = ctClass.getDeclaredMethod("hello", new CtClass[]{classPool.get("java.lang.String")});
    16. // 修改方法的访问权限为private
    17. helloMethod.setModifiers(Modifier.PRIVATE);
    18. // 输出hello方法的content参数值
    19. helloMethod.insertBefore("System.out.println($1);");
    20. // 输出hello方法的返回值
    21. helloMethod.insertAfter("System.out.println($_); return \"Return:\" + $_;");
    22. File classFilePath = new File(new File(System.getProperty("user.dir"), "javaweb-sec-source/javase/src/main/java/com/anbai/sec/bytecode/"), "TestHelloWorld.class");
    23. // 使用类CtClass,生成类二进制
    24. byte[] bytes = ctClass.toBytecode();
    25. // 将class二进制内容写入到类文件
    26. FileUtils.writeByteArrayToFile(classFilePath, bytes);
    27. } catch (Exception e) {
    28. e.printStackTrace();
    29. }
    30. }
    31. }

    程序执行后结果如下:
    4. 修改类方法 - 图1