如何基于javassist进行动态编程

  介绍

小编这次要给大家分享的是如何基于javassist进行动态编程,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。

今天在研究达博时,发现一个新的知识点,可以使用javassist包进行动态编程,hibernate也使用该包进行编程。晚上百度了很多资料,将它的特性以代码的形式展现出来。

包com.zhi.demo;
  
  进口java.lang.reflect.Field;
  
  进口javassist.ClassPool;
  进口javassist.CtClass;
  进口javassist.CtConstructor;
  进口javassist.CtField;
  进口javassist.CtMethod;
  进口javassist.CtNewConstructor;
  进口javassist.CtNewMethod;
  进口javassist.Loader;
  进口javassist.Modifier;
  进口javassist.bytecode.AccessFlag;/* *
  * Javassist动态编程测试
  *
  * @date 2019年03月11日23:00:33
  *
  */公开课javassist {
  公共静态void main (String [] args) {
  尝试{
  测试();
  }捕捉(异常e) {
  e.printStackTrace ();
  }
  }
  
  私有静态空白测试()抛出异常{
  System.out.println(“- - - - - - - - - - - - - - - - - - -新增类- - - - - - - - - - - - - - - - - -“);
  ClassPool池=ClassPool.getDefault ();//创建类
  CtClass ct=pool.makeClass (“com.zhi.Person");//让类实现可克隆接口
  ct。setInterfaces(新CtClass [] {pool.makeInterface (“java.lang.Cloneable")});//添加一个int类型的共有属性
  CtField fieldId=new CtField (CtClass.intType“id", ct);
  fieldId.setModifiers (AccessFlag.PUBLIC);
  ct.addField (fieldId);//添加一个默认构造器
  CtConstructor constructor1=CtNewConstructor.make(“公众人物(){this.id=1;}“, ct);
  ct.addConstructor (constructor1);//添加方法
  CtMethod helloM=CtNewMethod
  使(“公共空间你好(String des) {System.out.println(\“执行你好方法,\“+ des + \“,我的身份证是\“+ this.id);}“, ct);
  ct.addMethod (helloM);//将生成的. class文件保存到磁盘
  ct.writeFile ();//加载目标类,可用ct.toClass()或新的装载机(池).loadClass ()
  Class<及# 63;比;clazz=ct.toClass ();//Class<及# 63;比;clazz=new装载机(池).loadClass (“com.zhi.Person");//输出类基本信息
  System.out.println(“包名:“;+ clazz.getPackageName ());
  System.out.println(“类名:“;+ clazz.getName ());
  System.out.println(“简要类名:“+ clazz.getSimpleName ());
  System.out.println(“限定符:“;+ Modifier.toString (clazz.getModifiers ()));
  System.out.println(“继承类:“;+ clazz.getSuperclass () . getname ());
  ?[]字段clazz.getDeclaredFields ();
  (字段字段:字段){
  System.out.println(“属性名称:“+ field.getName() +“,属性类型:“+ field.getType() +“限定符:“
  + Modifier.toString (field.getModifiers ()));
  }//构造一个对象,并执行你好方法
  .newInstance对象ob=clazz.getDeclaredConstructor () ();
  clazz.getMethod (“hello" String.class)。调用(ob,“张三“);//解冻(执行toClass后会自动冻结)
  ct.defrost ();
  
  System.out.println(“- - - - - - - - - - - - - - - - - - -修改类- - - - - - - - - - - - - - - - - -“);//添加一个字符串类型的私有属性
  CtField fieldName=new CtField (pool.get (String.class.getName ()),“name", ct);
  fieldName.setModifiers (AccessFlag.PRIVATE);
  ct.addField(字段名);//添加带参的构造函数
  CtConstructor constructor2=new CtConstructor(新CtClass [] {pool.get (String.class.getName ())}, ct);
  constructor2.setModifiers (Modifier.PUBLIC);
  constructor2.setBody (“{this.name=1美元;}“);
  ct.addConstructor (constructor2);
  
  ct.addMethod (CtNewMethod.make(“公共空setName(字符串名称){this.name=名字;}“,ct));
  ct.addMethod (CtNewMethod.make(“公共字符串getName(){返回this.name;}“, ct));
  
  ct.writeFile ();//加载类,若前面已用ct.toClass()进行加载,则这里不能再用ct.toClass()加载,否则会出错,同一个加载不能2次加载同一个类
  clazz=new装载机(池).loadClass (“com.zhi.Person");
  
  字段=clazz.getDeclaredFields ();
  (字段字段:字段){
  System.out.println(“属性名称:“+ field.getName() +“,属性类型:“+ field.getType() +“限定符:“
  + Modifier.toString (field.getModifiers ()));
  }
  
  ob=clazz.getDeclaredConstructor (String.class) .newInstance(“马云“);
  System.out.println(“执行getName方法得到的值为:“+ clazz.getMethod (“getName") .invoke (ob));
  }
  }

执行上面代码输出结果为:

- - - - - - - - - - - - - - - - - - -新增类- - - - - - - - - - - - - - - - - -   包名:com.zhi   类名:com.zhi.Person   简要类名:人   限定符:公众   继承类:java . lang . object   属性名称:id,属性类型:int,限定符:公众   执行你好方法,张三,我的身份证是1   - - - - - - - - - - - - - - - - - - -修改类- - - - - - - - - - - - - - - - - -   属性名称:id,属性类型:int,限定符:公众   属性名称:名称,属性类型:以类,限定符:私有的   执行getName方法得到的值为:马云

如何基于javassist进行动态编程