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

.NET/liyangbing315/article/details/5472862
你可以利用ASM动态操作class

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

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

asm-3.3.1.jar详解 (转)的更多相关文章

  1. 转:关于将Java编译过的.class文件打成jar可执行文件/JAR详解

    原文链接:关于将Java编译过的.class文件打成jar可执行文件/JAR详解 如何把 java 程序编译成 .exe 文件.通常回答只有两种,一种是制作一个可执行的 JAR 文件包,然后就可以像. ...

  2. eclipse生成export生成jar详解

    使用eclipse打jar包可能还有很多人不是很了解,今天特意测试整理一番. 打jar包有3种形式 JAR file               JAR Javadoc              ja ...

  3. Oracle 10g RAC (linux) ASM 共享存储的管理详解

    ---------ASM 的管理(共享磁盘的管理)1.以 instance 的方式管理 ASM,启动 database 之前必须先启动 ASM instance,ASM instance 启动后,挂载 ...

  4. Spring jar包详解

    Spring jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spri ...

  5. Spring——jar包详解(转)

    Spring——jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spr ...

  6. Spring 3.x jar 包详解 与 依赖关系

    以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...

  7. Spring 3.x jar 包详解 与 依赖关系(转)

    以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...

  8. 常见 jar包详解

        常见 jar包详解 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期 ...

  9. Spring各个jar包详解

    Spring各jar包详解 spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar,aspects.jar, spring-portlet.jar, and sprin ...

随机推荐

  1. Enables DNS lookups on client IP addresses

    w虚拟域名访问,路由可以到达,但无输出. http://httpd.apache.org/docs/2.2/mod/core.html#hostnamelookups

  2. qt and redis desktop manager

    (ubuntu desktop)http://blog.csdn.net/ficksong/article/details/7497827 redis manager in ubuntu wget h ...

  3. Vue1.x 到Vue2.0的一个变化

    小弟初来乍到,写的不好的地方还望指正.谢谢各位! 废话不多说  进入正题: Vue1.x到2.0的一个变化 1. 在每个组件模板,不在支持片段代码  组件中模板: 之前:     <templa ...

  4. Linux 下的同步机制

    2017-03-10 回想下最初的计算机设计,在单个CPU的情况下,同一时刻只能由一个线程(在LInux下为进程)占用CPU,且2.6之前的Linux内核并不支持内核抢占,当进程在系统地址运行时,能打 ...

  5. 3.Github介绍

    很多人都知道,Linus在1991年创建了开源的Linux.从此,Linux系统不断发展,已经成为最大的服务器系统软件了.Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的 ...

  6. 002-shell变量定义、使用、字符串、数组、注释

    一.变量定义 定义变量时,变量名不加美元符号($) name="lhx" 注意,变量名和等号之间不能有空格.同时,变量名的命名须遵循如下规则: 命名只能使用英文字母,数字和下划线, ...

  7. 单舵轮(叉车)AGV里程计数据解算

    单舵轮(叉车)AGV里程计数据解算 2016-07 单舵轮AGV,一般包含一个驱动轮和两个从动轮,驱动轮是同时具备行走和转向两个功能的舵轮,因此,单舵轮AGV的运动学自由度为2个.舵轮线速度V1,舵轮 ...

  8. 安装CentOS 7 文字版

    下载镜像 http://mirrors.163.com/ CentOS 7.4 http://mirrors.163.com/centos/7.4.1708/isos/x86_64/ 选择 CentO ...

  9. oracle dataguard参数

    在整个dg配置中,最复杂的也许就是参数的配置了,并且有许多参数都可以延伸出去讲很多,所以今天我们来看看dg的参数配置,顺便加上一点dataguard进程相关的信息,帮助理解. 在配置dg的过程中,我们 ...

  10. matplotlib绘制柱状图

    参考自Matplotlib Python 画图教程 (莫烦Python)(11)_演讲•公开课_科技_bilibili_哔哩哔哩 https://www.bilibili.com/video/av16 ...