Javassist动态创建类

近日研究mybatis 然后发现他的默认代理框架是Javassist,日本人搞的.

创建代理对象也是直接写了一个ClassFile,然后通过classLoder 加载进来.

package test;

import javassist.*;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    private String a = "吵吵机器人";

    public String getA() {
        return a;
    }

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException, NotFoundException, CannotCompileException, ClassNotFoundException, NoSuchMethodException {
        ClassPool pool = ClassPool.getDefault();
        // 创建类 炉石传说
        CtClass 炉石传说 = pool.makeClass("炉石传说");
        // 创建属性 炉石第一卡
        CtField 炉石第一卡 = new CtField(pool.get("java.lang.String"), "炉石第一卡", 炉石传说);
        //设置炉石第一卡的访问修饰符为private
        炉石第一卡.setModifiers(Modifier.PRIVATE);
        炉石传说.addField(炉石第一卡);
        //给炉石第一卡增加get set方法
        炉石传说.addMethod(CtNewMethod.setter("set炉石第一卡", 炉石第一卡));
        炉石传说.addMethod(CtNewMethod.getter("get炉石第一卡", 炉石第一卡));
        //给炉石传说增加无参构造函数
        CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, 炉石传说);
        ctConstructor.setBody("{炉石第一卡=\"砰砰博士\";}");
        炉石传说.addConstructor(ctConstructor);
        //创建有参构造函数
        ctConstructor = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, 炉石传说);
        ctConstructor.setBody("{$0.炉石第一卡=$1;}");
        炉石传说.addConstructor(ctConstructor);
        //打印创建类名
        System.out.println(炉石传说.toClass());
        //实例化对象
        Object 暴雪 = Class.forName("炉石传说").newInstance();
        Class<?> 炉石Class = 暴雪.getClass();
        Field field = 炉石Class.getDeclaredField("炉石第一卡");
        //将私有访问修饰符改成公有
        field.setAccessible(true);
        field.set(暴雪, "岩浆暴怒者");
        Method get炉石第一卡 = 炉石Class.getMethod("get炉石第一卡");
        System.out.println(get炉石第一卡.invoke(暴雪));
    }
}

不要吐槽代码规范的问题,学习的代码想怎么写怎么写.

运行结果:

猜你喜欢

转载自blog.csdn.net/jidong2622/article/details/84319864