此文已由作者赵计刚薪授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
假设要使用javassist创建一个类:
1 package com.alibaba.dubbo.demo.test; 2 3 public class Emp { 4 //属性 5 private int account; 6 private String name; 7 8 //构造方法 9 public Emp() { 10 this.account = 1; 11 this.name = "xiaona"; 12 } 13 14 //getter 15 public int getAccount() { 16 return account; 17 } 18 19 //setter 20 public void setAccount(int account) { 21 this.account = account; 22 } 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 //普通方法 33 public void commonMethod() { 34 System.out.println("haha"); 35 } 36 }
该类包含属性/构造方法/getter/setter/普通方法。
使用javassist来创建类:
1 package com.alibaba.dubbo.demo.test; 2 3 import javassist.ClassPool; 4 import javassist.CtClass; 5 import javassist.CtConstructor; 6 import javassist.CtField; 7 import javassist.CtMethod; 8 import javassist.CtNewMethod; 9 import javassist.Modifier; 10 11 import java.io.File; 12 import java.io.FileOutputStream; 13 14 public class TestJavassitCompiler { 15 public static void main(String[] args) throws Exception { 16 ClassPool pool = ClassPool.getDefault(); 17 CtClass ctClass = pool.makeClass("com.alibaba.dubbo.demo.test.Emp"); 18 //添加属性:private String name 19 CtField nameField = new CtField(pool.getCtClass("java.lang.String"), "name", ctClass); 20 nameField.setModifiers(Modifier.PRIVATE); 21 ctClass.addField(nameField); 22 //添加属性:private int account 23 CtField accountField = new CtField(pool.getCtClass("int"), "account", ctClass); 24 accountField.setModifiers(Modifier.PRIVATE); 25 ctClass.addField(accountField); 26 //getter和setter 27 ctClass.addMethod(CtNewMethod.getter("getName", nameField)); 28 ctClass.addMethod(CtNewMethod.setter("setName", nameField)); 29 ctClass.addMethod(CtNewMethod.getter("getAccount", accountField)); 30 ctClass.addMethod(CtNewMethod.setter("setAccount", accountField)); 31 //创建构造器 32 CtConstructor ctConstructor = new CtConstructor(new CtClass[] {}, ctClass); 33 String body = new StringBuilder("{\nthis.account = 1;\nthis.name = \"xiaona\";\n}").toString(); 34 ctConstructor.setBody(body); 35 ctClass.addConstructor(ctConstructor); 36 //普通方法 37 CtMethod ctMethod = new CtMethod(CtClass.voidType, "commonMethod", new CtClass[] {}, ctClass); 38 ctMethod.setModifiers(Modifier.PUBLIC); 39 ctMethod.setBody(new StringBuilder("{\n System.out.println(\"haha\"); \n}").toString()); 40 ctClass.addMethod(ctMethod); 41 42 Class<?> clazz = ctClass.toClass(); 43 Object obj = clazz.newInstance(); 44 obj.getClass().getMethod("commonMethod", new Class[] {}).invoke(obj, new Object[] {});//方法调用 45 46 /** 47 * 将字节码输出到文件中 48 */ 49 byte[] codeByteArray = ctClass.toBytecode(); 50 FileOutputStream fos = new FileOutputStream(new File("/Users/jigangzhao/Desktop/Emp.class")); 51 fos.write(codeByteArray); 52 fos.close(); 53 } 54 }
之后可以使用javap命令来看一下/Users/jigangzhao/Desktop/Emp.class文件。
关于javassit的API请查看:
https://github.com/jboss-javassist/javassist/wiki/Tutorial-1
更多网易技术、产品、运营经验分享请点击。