近日研究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(暴雪));
}
}
不要吐槽代码规范的问题,学习的代码想怎么写怎么写.
运行结果: