Javassist2-使用实例

来源:互联网 发布:mysql查看数据库编码 编辑:程序博客网 时间:2024/06/05 18:15

上篇博客简单介绍了一下javassist工具,这篇博客利用javassist工具来动态的生成一个class文件,并且简单介绍一下我在产品中是如何利用这个工具包的。

 

一般的类的组成就是类名称,属性,属性的setter和getter方法,构造函数以及方法。

 

那么这个实例就是利用javassist工具生成这样一个class文件的,具体流程为通过CtClas对象的容器ClassPool创建一个类,添加字段,生成set和get方法,之后生成构造函数,添加方法,并且调用方法执行,最后将class文件写到文件中。

 

具体代码如下

 

package test; import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.InvocationTargetException; import javassist.CannotCompileException;import javassist.ClassPool;import javassist.CtClass;import javassist.CtConstructor;import javassist.CtField;import javassist.CtMethod;import javassist.CtNewMethod;import javassist.Modifier;import javassist.NotFoundException; public class TestJavassist01 { /** * @param args * @throws IllegalAccessException * @throws InstantiationException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws SecurityException * @throws IllegalArgumentException */public static void main(String[] args) throws InstantiationException,IllegalAccessException, IllegalArgumentException,SecurityException, InvocationTargetException, NoSuchMethodException { //CtClass对象容器ClassPool pool = ClassPool.getDefault();try {//创建ClassCtClass cc = pool.makeClass("Man");//阻止优化调整:优化调整减少内存使用,去除对象内的一些不必要的属性,优化调整后,方法签名和注解都是不可访问的cc.stopPruning(true); //添加name属性CtField f = new CtField(pool.get("java.lang.String"), "name", cc);f.setModifiers(Modifier.PRIVATE);cc.addField(f); //生成get/set方法cc.addMethod(CtNewMethod.getter("getName", f));cc.addMethod(CtNewMethod.setter("setName", f)); //生成构造函数CtConstructor c = new CtConstructor(new CtClass[] {}, cc);c.setBody("{\n" + "name=\"cjq\";\n}");cc.addConstructor(c); //添加say方法CtMethod ctm = new CtMethod(CtClass.voidType, "say",new CtClass[] {}, cc);ctm.setModifiers(Modifier.PUBLIC);ctm.setBody("{\nSystem.out.println(\"my name is \"+ name);\n}");cc.addMethod(ctm);//调用生成的class类中的方法/这里可以用toClass()方法来加载类,也可以用java的类加载器来加载Class<?> clazz = cc.toClass();Object o = clazz.newInstance();o.getClass().getMethod("say", new Class[] {}).invoke(o, new Object[] {});//将class文件输出到系统文件中byte[] byteArr = cc.toBytecode();FileOutputStream fos = new FileOutputStream(new File("D://Man.class"));fos.write(byteArr);fos.close(); } catch (NotFoundException e) {e.printStackTrace();} catch (CannotCompileException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}

输出结果:

 


 

生成的class文件如下:



 

 这样就通过javassist工具生成了一个class文件。

 

那么我在工作中是通过javassist生成了一些class文件,主要是配合Groovy语言调用使用的,Groovy可以执行脚本也可以执行class文件,当发现执行脚本会比直接执行class文件慢的情况下,我们会在产品运行之前先将预知的脚本生成class文件,这里就用到了javassist,这样的话在运行过程中性能得到了提升,这是我在工作中运用的javassist解决了一些性能问题。希望大家能够玩玩这个工具。

 

0 0
原创粉丝点击