JavaSsist的使用 - pingdongyi/blog-2 GitHub Wiki

详情见测试项目

添加依赖

<!--Javassist是一个开源的分析、编辑和创建Java字节码的类库,
    jdk1.8必须用javassist3.18以上版本
-->
<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.21.0-GA</version>
</dependency>

应用示例

package com.ibingbo;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;

/**
 * jdk1.8必须用javassist3.18以上版本
 *
 * @author zhangbingbing
 * @title JavaSsistTest
 * @date 17/10/16
 */
public class JavaSsistTest {
    public static void main(String[] args)
            throws Exception {
        createClass();
        getClassInfo();
        addAndEidtMethod();
    }

    /**
     * 添加修改方法
     */
    public static void addAndEidtMethod() throws Exception {

        ClassPool classPool = ClassPool.getDefault();
        CtClass ctClass = classPool.get("com.ibingbo.People");

        CtClass[] paramTypes = {classPool.get(String.class.getName())};
        CtMethod method = ctClass.getDeclaredMethod("show", paramTypes);
        // 复制方法
        CtMethod newMethod = CtNewMethod.copy(method, ctClass, null);

        String oldName = method.getName() + "$Impl";
        // 修改原方法名
        method.setName(oldName);

        // 修改新方法体
        newMethod.setBody("{System.out.println(\"执行前\");" + oldName + "($$);System.out.println(\"执行后\");System.out"
                + ".println(\"hi,\"+$1);}");
        ctClass.addMethod(newMethod);

        Class<?> cls = ctClass.toClass();
        cls.getMethod("show", String.class).invoke(cls.newInstance(), "world");
        ctClass.defrost();
    }

    /**
     * 获取类信息
     *
     * @throws Exception
     */
    public static void getClassInfo() throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        CtClass ctClass = classPool.get("com.ibingbo.User");
        System.out.println(ctClass.getName());
        System.out.println("package: " + ctClass.getPackageName());
        System.out.println(Modifier.toString(ctClass.getModifiers()) + " class " + ctClass.getSimpleName());
        System.out.println("extends " + ctClass.getSuperclass().getName());
        if (ctClass.getInterfaces() != null && ctClass.getInterfaces().length > 0) {
            System.out.println("implements ");
            boolean first = true;
            for (CtClass c : ctClass.getInterfaces()) {
                if (first) {
                    first = false;
                } else {
                    System.out.print(", ");

                }
                System.out.print(c.getName());
            }
        }
        System.out.println();

    }

    /**
     * 动态创建类
     *
     * @throws Exception
     */
    public static void createClass() throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        // 创建一个类
        CtClass ctClass = classPool.makeClass("com.ibingbo.Student");
        // 新建一个属性
        CtField field = new CtField(classPool.get(Integer.class.getName()), "id", ctClass);
        field.setModifiers(Modifier.PRIVATE);

        // 添加getter,setter方法
        ctClass.addMethod(CtNewMethod.setter("setId", field));
        ctClass.addMethod(CtNewMethod.getter("getId", field));
        ctClass.addField(field);

        // 添加默认构造函数
        CtConstructor constructor = new CtConstructor(null, ctClass);
        constructor.setModifiers(Modifier.PUBLIC);
        constructor.setBody("{}");
        ctClass.addConstructor(constructor);

        // 添加有参构造函数
        constructor = new CtConstructor(new CtClass[] {classPool.get(Integer.class.getName())}, ctClass);
        constructor.setModifiers(Modifier.PUBLIC);
        constructor.setBody("{this.id=$1;}");
        ctClass.addConstructor(constructor);

        // 设置方法
        CtMethod method = new CtMethod(CtClass.voidType, "run", null, ctClass);
        method.setModifiers(Modifier.PUBLIC);
        method.setBody("{System.out.println(\"执行结果\" + this.id);}");
        ctClass.addMethod(method);

        // 加载和执行生成的类
        Class<?> clazz = ctClass.toClass();
        Object object = clazz.newInstance();
        clazz.getMethod("setId", Integer.class).invoke(object, 11);
        clazz.getMethod("run").invoke(object);

        object = clazz.getConstructor(Integer.class).newInstance(22);
        clazz.getMethod("run").invoke(object);

    }
}
⚠️ **GitHub.com Fallback** ⚠️