zoukankan      html  css  js  c++  java
  • asm-3.3.1.jar详解 (转)

    Java字节码操纵框架。它可以直接以二进制形式动态地生成stub类或其他代理类,或者在装载时动态地修改类。ASM提供类似于BCEL和SERP之类的工具包的功能,但是被设计得更小巧、更快速,这使它适用于实时代码插装。
    .NET/liyangbing315/article/details/5472862
    你可以利用ASM动态操作class

    我们知道Java是静态语言,而Pythonruby是动态语言,Java程序一旦写好很难在运行时更改类的行为,而Python、ruby可以。 
    不过基于bytecode层面上我们可以做一些手脚,来使Java程序多一些灵活性和Magic,ASM就是这样一个应用广泛的开源库。 

    ASM is a Java bytecode manipulation framework. It can be used to dynamically generatestub classes or other proxy classes, 
    directly in binary form, or to dynamically modify classes at load time, i.e., justbefore they are loaded into the Java 
    Virtual Machine. 

    ASM完成了BCELSERP同样的功能,但ASM 
    只有30多k,而后两者分别是350k和150k。apache真是越来越过气了。 

    让我们来看一个ASM的简单例子Helloworld.java,它生成一个Example类和一个main方法,main方法打印"Hello world!"语句:

    Java代码

    1. import java.io.FileOutputStream;   
    2. import java.io.PrintStream;   
    3.   
    4. import org.objectweb.asm.ClassWriter;   
    5. import org.objectweb.asm.MethodVisitor;   
    6. import org.objectweb.asm.Opcodes;   
    7. import org.objectweb.asm.Type;   
    8. import org.objectweb.asm.commons.GeneratorAdapter;   
    9. import org.objectweb.asm.commons.Method;   
    10.   
    11. public class Helloworld extends ClassLoader implements Opcodes {   
    12.   
    13.   public static void main(final String args[]) throws Exception {   
    14.   
    15.     // creates a ClassWriter for the Example public class,   
    16.     // which inherits from Object   
    17.   
    18.      ClassWriter cw = new ClassWriter(0);   
    19.      cw.visit(V1_1, ACC_PUBLIC, "Example", null"java/lang/Object", null);   
    20.      MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,   
    21.         null);   
    22.      mw.visitVarInsn(ALOAD, 0);   
    23.      mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");   
    24.      mw.visitInsn(RETURN);   
    25.      mw.visitMaxs(1, 1);   
    26.      mw.visitEnd();   
    27.      mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",   
    28.         "([Ljava/lang/String;)V", nullnull);   
    29.      mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",   
    30.         "Ljava/io/PrintStream;");   
    31.      mw.visitLdcInsn("Hello world!");   
    32.      mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",   
    33.         "(Ljava/lang/String;)V");   
    34.      mw.visitInsn(RETURN);   
    35.      mw.visitMaxs(2, 2);   
    36.      mw.visitEnd();   
    37.     byte[] code = cw.toByteArray();   
    38.      FileOutputStream fos = new FileOutputStream("Example.class");   
    39.      fos.write(code);   
    40.      fos.close();   
    41.      Helloworld loader = new Helloworld();   
    42.      Class exampleClass = loader   
    43.          .defineClass("Example", code, 0, code.length);   
    44.      exampleClass.getMethods()[0].invoke(nullnew Object[] { null });   
    45.   
    46.     // ------------------------------------------------------------------------   
    47.     // Same example with a GeneratorAdapter (more convenient but slower)   
    48.     // ------------------------------------------------------------------------   
    49.   
    50.      cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);   
    51.      cw.visit(V1_1, ACC_PUBLIC, "Example", null"java/lang/Object", null);   
    52.      Method m = Method.getMethod("void <init> ()");   
    53.      GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, nullnull,   
    54.          cw);   
    55.      mg.loadThis();   
    56.      mg.invokeConstructor(Type.getType(Object.class), m);   
    57.      mg.returnValue();   
    58.      mg.endMethod();   
    59.      m = Method.getMethod("void main (String[])");   
    60.      mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, nullnull, cw);   
    61.      mg.getStatic(Type.getType(System.class), "out", Type   
    62.          .getType(PrintStream.class));   
    63.      mg.push("Hello world!");   
    64.      mg.invokeVirtual(Type.getType(PrintStream.class), Method   
    65.          .getMethod("void println (String)"));   
    66.      mg.returnValue();   
    67.      mg.endMethod();   
    68.      cw.visitEnd();   
    69.      code = cw.toByteArray();   
    70.      loader = new Helloworld();   
    71.      exampleClass = loader.defineClass("Example", code, 0, code.length);   
    72.      exampleClass.getMethods()[0].invoke(nullnew Object[] { null });   
    73.    }   
    74. }  


    我们看到上面的例子分别使用ASM的MethodVisitor和GeneratorAdapter两种方式来动态生成Example类并调用打印语句。

  • 相关阅读:
    javascript Math.random()随机数函数
    asp.net 前台获取后台c#代码信息
    关于C#网站一般处理程序(ashx)中session的问题
    怎样才能在一般处理文件中创建新的Session和访问已经存在的Session?
    使用SqlParameter向数据库中插入数据
    C#串口编程学习简单实例
    认识nodejs
    01.Javascript中的接口Interface [转载]
    动态添加脚本,并触发回调函数 初步实现按需加载
    JS正则表达式 收藏
  • 原文地址:https://www.cnblogs.com/Syria/p/6551286.html
Copyright © 2011-2022 走看看