Java AES 加密算法

Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态”AOP”框架。

关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

下面我们就用使用Javassist来创建一个类,并调用其中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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)只支持查询,不支持添加或修改

参考文章/推荐阅读:

  1. 用 Javassist 进行类转换
  2. Javassist的官方网站
  3. javassist 学习笔记
  4. javassist学习
  5. Javassist学习总结
    `
上一篇