javassist實例

咱們經常使用到的動態特性主要是反射,在運行時查找對象屬性、方法,修改做用域,經過方法名稱調用方法等。在線的應用不會頻繁使用反射,由於反射的性能開銷較大。其實還有一種和反射同樣強大的特性,可是開銷卻很低,它就是Javassist。java

Javassist其實就是一個二方包,提供了運行時操做Java字節碼的方法。Java代碼編譯完會生成.class文件,就是一堆字節碼。JVM(準確說是JIT)會解釋執行這些字節碼(轉換爲機器碼並執行),因爲字節碼的解釋執行是在運行時進行的,那咱們可否手工編寫字節碼,再由JVM執行呢?答案是確定的,而Javassist就提供了一些方便的方法,讓咱們經過這些方法生成字節碼。函數

 

重要的類:性能

ClassPool:javassist的類池,使用ClassPool 類能夠跟蹤和控制所操做的類,它的工做方式與 JVM 類裝載器很是類似,
CtClass: CtClass提供了檢查類數據(如字段和方法)以及在類中添加新字段、方法和構造函數、以及改變類、父類和接口的方法。不過,Javassist 並未提供刪除類中字段、方法或者構造函數的任何方法。
CtField:用來訪問域
CtMethod :用來訪問方法
CtConstructor:用來訪問構造器

this

實例:spa

Example1:code

 1 public class Example1 {
 2     public static void main(String[] args) throws Exception {
 3         ClassPool pool = ClassPool.getDefault();
 4         CtClass cc = pool.makeClass("bean.User");
 5 
 6         //建立屬性
 7         CtField field01 = CtField.make("private int id;",cc);
 8         CtField field02 = CtField.make("private String name;", cc);
 9         cc.addField(field01);
10         cc.addField(field02);
11 
12         //建立方法
13         CtMethod method01 = CtMethod.make("public String getName(){return name;}", cc);
14         CtMethod method02 = CtMethod.make("public void setName(String name){this.name = name;}", cc);
15         cc.addMethod(method01);
16         cc.addMethod(method02);
17 
18         //添加有參構造器
19         CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType, pool.get("java.lang.String")}, cc);
20         constructor.setBody("{this.id=id;this.name=name;}");
21         cc.addConstructor(constructor);
22         //無參構造器
23         CtConstructor cons = new CtConstructor(null, cc);
24         cons.setBody("{}");
25         cc.addConstructor(cons);
26 
27         cc.writeFile("E:/workspace/TestCompiler/src");
28     }
29 }

 

Person:對象

 1 public class Person {
 2 
 3     public Person() {}
 4 
 5     public Person(int id, String name) {
 6         this.id = id;
 7         this.name = name;
 8     }
 9 
10     private int id;
11 
12     private String name;
13 
14     public int getId() {
15         return id;
16     }
17 
18     public void setId(int id) {
19         this.id = id;
20     }
21 
22     public String getName() {
23         return name;
24     }
25 
26     public void setName(String name) {
27         this.name = name;
28     }
29 
30     public String hello(String name) {
31         return name;
32     }
33 
34 }

 

Example2:blog

 1 public class Example2 {
 2 
 3     //獲取類的簡單信息
 4     public static void test01() throws Exception{
 5         ClassPool pool = ClassPool.getDefault();
 6         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
 7         //獲得字節碼
 8         byte[] bytes = cc.toBytecode();
 9         System.out.println(Arrays.toString(bytes));
10         System.out.println(cc.getName());//獲取類名
11         System.out.println(cc.getSimpleName());//獲取簡要類名
12         System.out.println(cc.getSuperclass());//獲取父類
13         System.out.println(cc.getInterfaces());//獲取接口
14         System.out.println(cc.getMethods());//獲取
15     }
16     //新生成一個方法
17     public static void test02() throws Exception{
18         ClassPool pool = ClassPool.getDefault();
19         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
20         //第一種
21         //CtMethod cm = CtMethod.make("public String getName(){return name;}", cc);
22         //第二種
23         //參數:返回值類型,方法名,參數,對象
24         CtMethod cm = new CtMethod(CtClass.intType,"add", new CtClass[]{CtClass.intType, CtClass.intType}, cc);
25         cm.setModifiers(Modifier.PUBLIC);//訪問範圍
26         cm.setBody("{return $1+$2;}");
27         //cc.removeMethod(m) 刪除一個方法
28         cc.addMethod(cm);
29         //經過反射調用方法
30         Class clazz = cc.toClass();
31         Object obj = clazz.newInstance();//經過調用無參構造器,生成新的對象
32         Method m = clazz.getDeclaredMethod("add", int.class, int.class);
33         Object result = m.invoke(obj, 2, 3);
34         System.out.println(result);
35     }
36 
37     //修改已有的方法
38     public static void test03() throws Exception{
39         ClassPool pool  = ClassPool.getDefault();
40         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
41 
42         CtMethod cm = cc.getDeclaredMethod("hello",new CtClass[]{pool.get("java.lang.String")});
43         cm.insertBefore("System.out.println(\"調用前\");");//調用前
44         cm.insertAt(31, "System.out.println(\"31\");");//行號
45         cm.insertAfter("System.out.println(\"調用後\");");//調用後
46 
47         //經過反射調用方法
48         Class clazz = cc.toClass();
49         Object obj = clazz.newInstance();
50         Method m = clazz.getDeclaredMethod("hello", String.class);
51         Object result = m.invoke(obj, "張三");
52         System.out.println(result);
53     }
54 
55     //修改已有屬性
56     public static void test04() throws Exception{
57         ClassPool pool  = ClassPool.getDefault();
58         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
59 
60         //屬性
61         CtField cf = new CtField(CtClass.intType,"age",cc);
62         cf.setModifiers(Modifier.PRIVATE);
63         cc.addField(cf);
64         //增長響應的get set方法
65         cc.addMethod(CtNewMethod.getter("getAge",cf));
66         cc.addMethod(CtNewMethod.setter("setAge",cf));
67 
68         //訪問屬性
69         Class clazz = cc.toClass();
70         Object obj = clazz.newInstance();
71         Field field = clazz.getDeclaredField("age");
72         System.out.println(field);
73         Method m = clazz.getDeclaredMethod("setAge", int.class);
74         m.invoke(obj, 16);
75         Method m2 = clazz.getDeclaredMethod("getAge", null);
76         Object resutl = m2.invoke(obj,null);
77         System.out.println(resutl);
78     }
79 
80     //操做構造方法
81     public static void test05() throws Exception{
82         ClassPool pool = ClassPool.getDefault();
83         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
84 
85         CtConstructor[] cons = cc.getConstructors();
86         for(CtConstructor con:cons){
87             System.out.println(con);
88         }
89     }
90     public static void main(String[] args) throws Exception {
91         test01();
92 //        test02();
93 //        test03();
94 //        test04();
95 //        test05();
96     }
97 }
相關文章
相關標籤/搜索