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. 修改\Servlet和Jsp模板的方法

    1.在MyEclipse6.6\myeclipse\eclipse\plugins下找到com.genuitec.eclipse.wizards 2.templates\替换Servlet.java ...

  2. 【转】VMwareCLI命令参考

    VMwareCLI命令参考 目录 基本命令范例 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 2 ...

  3. 剑指Offer——平衡二叉树

    题目描述: 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 分析: 平衡二叉树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质 ...

  4. JAVA—List集合总结

    List接口总结: List接口是Collection接口的子接口,从其名称可以看出,是一个元素有序(并不是按大小排序,具有顺序索引,类似于数组),默认按照元素的添加顺序设置元素的索引,List和Se ...

  5. replace未全局替换的坑

    今天是名副其实的周六.悠闲了一早上(太阳). 真是人在家中坐,BUG自天上来.哈哈其实也不是自天上来,还是自己之前埋下的雷. 所以修复完线上的bug,我脑中立刻浮现出两件还需要做的事情: 一,就是我现 ...

  6. x86架构下的控制寄存器CR0-CR4

    关于这几个寄存器,每次翻看intel手册都很不好找,干脆直接贴在这里吧!

  7. Mysql2索引

    索引分类: 作用:优化查询,select查询有三种情况:缓存查询(不在mysql中进行数据查询),全表查询,索引扫描 Btree(btree b+tree b*tree) Rtree HASH Ful ...

  8. 【开发者笔记】插入排序过程呈现之java内置GUI表示

    先给代码,再给过程视频: package com.dyi.wyb.sort; import java.awt.Color; import java.awt.Graphics; import java. ...

  9. linux 下路由配置

    转自 https://www.cnblogs.com/kevingrace/p/6490627.html 在日常运维作业中,经常会碰到路由表的操作.下面就linux运维中的路由操作做一梳理:----- ...

  10. python16_day25【crm】

    一.CRM模拟admin功能 1.过滤功能 2.显示数据分页 3.动态菜单 项目:https://github.com/willianflasky/growup/tree/master/s16/hom ...