Java AES 加密算法
Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态”AOP”框架。
关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
下面我们就用使用Javassist来创建一个类,并调用其中的方法
1 | package com.carlzone.dubbo.javassist;import javassist.*;import java.io.File;import java.io.FileOutputStream;import java.lang.reflect.Modifier;public class CompilerByJavassist { public static void main(String[] args) throws Exception { // ClassPool: CtClass对象容器 ClassPool pool = ClassPool.getDefault(); // 通过ClassPool生成一个public的User类 CtClass ctClass = pool.makeClass("com.carlzone.learn.javassist.User"); // 添加属性 // 1. 添加属性private int id; CtField idField = new CtField(pool.getCtClass("int"), "id", ctClass); idField.setModifiers(Modifier.PRIVATE); ctClass.addField(idField); // 2.添加属性private String username CtField nameField = new CtField(pool.get("java.lang.String"), "username", ctClass); nameField.setModifiers(Modifier.PRIVATE); ctClass.addField(nameField); // 添加setter/getter方法 ctClass.addMethod(CtNewMethod.getter("getId", idField)); ctClass.addMethod(CtNewMethod.setter("setId", idField)); ctClass.addMethod(CtNewMethod.getter("getUsername", nameField)); ctClass.addMethod(CtNewMethod.setter("setUsername", nameField)); // 添加构造函数 CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); // 添加构造函数方法体 StringBuffer sb = new StringBuffer(); sb.append("{\n").append("this.id = 27;\n").append("this.username=\"carl\";\n}"); ctConstructor.setBody(sb.toString()); ctClass.addConstructor(ctConstructor); // 添加自定义方法 CtMethod printMethod = new CtMethod(CtClass.voidType, "print", new CtClass[]{}, ctClass); printMethod.setModifiers(Modifier.PUBLIC); StringBuffer printSb = new StringBuffer(); printSb.append("{\nSystem.out.println(\"begin!\");\n") .append("System.out.println(id);\n") .append("System.out.println(username);\n") .append("System.out.println(\"end!\");\n") .append("}"); printMethod.setBody(printSb.toString()); ctClass.addMethod(printMethod); // 生成一个Class Class<?> clazz = ctClass.toClass(); Object obj = clazz.newInstance(); // 反射执行方法 obj.getClass().getMethod("print", new Class[]{}).invoke(obj, new Object[]{}); // 把生成的class写入到文件中 byte[] byteArr = ctClass.toBytecode(); FileOutputStream fos = new FileOutputStream(new File("D://User.class")); fos.write(byteArr); fos.close(); }} |
我们来看一下创建这个对象的全部过程:
- 声明对象的全类名
- 创建field,并设置getter/setter方法
- 创建对象的无参构造器
- 创建自定义方法
其实这个过程就相当于我们手写了这样一个类,下面我们来运行一下这个类:
下面我们到D盘去用反编译工具看一下生成的Class文件。
最后需要特别注意的是:
- Javassist不支持要创建或注入的类中存在泛型参数
- Javassist对@类型的注解(Annotation)只支持查询,不支持添加或修改
参考文章/推荐阅读: