javassist基本使用

勿忘初心2018-11-18 12:03

此文已由作者赵计刚薪授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


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


免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击