这样和妻子解释:Java动态代理机制详解(JDK和CGLIB( 二 )


不过ASM在创建class字节码的过程中 , 操纵的级别是底层JVM的汇编指令级别 , 这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解 。
下面通过ASM 生成下面类Programmer的class字节码:
package com.samples;import java.io.PrintStream;public class Programmer {public void code(){System.out.println("I'm a Programmer,Just Coding.....");}}使用ASM框架提供了ClassWriter 接口 , 通过访问者模式进行动态创建class字节码 , 看下面的例子:
package samples;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;public class MyGenerator {public static void main(String[] args) throws IOException {System.out.println();ClassWriter classWriter = new ClassWriter(0);// 通过visit方法确定类的头部信息classWriter.visit(Opcodes.V1_7,// java版本Opcodes.ACC_PUBLIC,// 类修饰符"Programmer", // 类的全限定名null, "java/lang/Object", null);//创建构造函数MethodVisitor mv = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null);mv.visitCode();mv.visitVarInsn(Opcodes.ALOAD, 0);mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "","()V");mv.visitInsn(Opcodes.RETURN);mv.visitMaxs(1, 1);mv.visitEnd();// 定义code方法MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "code", "()V",null, null);methodVisitor.visitCode();methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out","Ljava/io/PrintStream;");methodVisitor.visitLdcInsn("I'm a Programmer,Just Coding.....");methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println","(Ljava/lang/String;)V");methodVisitor.visitInsn(Opcodes.RETURN);methodVisitor.visitMaxs(2, 2);methodVisitor.visitEnd();classWriter.visitEnd();// 使classWriter类已经完成// 将classWriter转换成字节数组写到文件里面去byte[] data = http://kandian.youth.cn/index/classWriter.toByteArray();File file = new File("D://Programmer.class");FileOutputStream fout = new FileOutputStream(file);fout.write(data);fout.close();}}上述的代码执行过后 , 用Java反编译工具(如JD_GUI)打开D盘下生成的Programmer.class , 可以看到以下信息:
这样和妻子解释:Java动态代理机制详解(JDK和CGLIB文章插图
再用上面我们定义的类加载器将这个class文件加载到内存中 , 然后 创建class对象 , 并且实例化一个对象 , 调用code方法 , 会看到下面的结果:
这样和妻子解释:Java动态代理机制详解(JDK和CGLIB文章插图
以上表明:在代码里生成字节码 , 并动态地加载成class对象、创建实例是完全可以实现的 。
Java字节码生成开源框架介绍--Javassist:
Javassist是一个开源的分析、编辑和创建Java字节码的类库 。 是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的 。 它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架 。 javassist是jboss的一个子项目 , 其主要的优点 , 在于简单 , 而且快速 。 直接使用java编码的形式 , 而不需要了解虚拟机指令 , 就能动态改变类的结构 , 或者动态生成类 。