1. 程式人生 > >5.1 javassist基本使用

5.1 javassist基本使用

logs ati lang stat etc str 調用 stringbu array

假設要使用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

5.1 javassist基本使用