asm 4.0 版本

http://forge.ow2.org/plugins/scmsvn/index.php?group_id=23

asm是java的字节码操作框架,可以动态查看类的信息,动态修改,删除,增加类的方法。

下面基于4.0版本的一个使用示例,演示了对类Foo进行修改方法名称,增加方法,修改方法内容等

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;public class AsmExample extends ClassLoader implements Opcodes{public static  class Foo {public static void execute() {System.out.println("test changed method name");}public static void changeMethodContent() {System.out.println("test change method");}}public static void main(String[] args) throws IOException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException {ClassReader cr = new ClassReader(Foo.class.getName());ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);ClassVisitor cv = new MethodChangeClassAdapter(cw);cr.accept(cv, Opcodes.ASM4);//新增加一个方法MethodVisitor mw= cw.visitMethod(ACC_PUBLIC + ACC_STATIC,"add","([Ljava/lang/String;)V",null,null);// pushes the 'out' field (of type PrintStream) of the System classmw.visitFieldInsn(GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");// pushes the "Hello World!" String constantmw.visitLdcInsn("this is add method print!");// invokes the 'println' method (defined in the PrintStream class)mw.visitMethodInsn(INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");mw.visitInsn(RETURN);// this code uses a maximum of two stack elements and two local// variablesmw.visitMaxs(0, 0);mw.visitEnd();// gets the bytecode of the Example class, and loads it dynamicallybyte[] code = cw.toByteArray();AsmExample loader = new AsmExample();Class<?> exampleClass = loader.defineClass(Foo.class.getName(), code, 0, code.length);for(Method method:  exampleClass.getMethods()){System.out.println(method);}System.out.println("*************");// uses the dynamically generated class to print 'Helloworld'exampleClass.getMethods()[0].invoke(null, null);  //調用changeMethodContent,修改方法內容System.out.println("*************");exampleClass.getMethods()[1].invoke(null, null); //調用execute,修改方法名// gets the bytecode of the Example class, and loads it dynamicallyFileOutputStream fos = new FileOutputStream("e:\\logs\\Example.class");fos.write(code);fos.close();}static class MethodChangeClassAdapter extends ClassVisitor implements Opcodes {public MethodChangeClassAdapter(final ClassVisitor cv) {super(Opcodes.ASM4, cv);}@Overridepublic void visit(int version,int access,String name,String signature,String superName,String[] interfaces){if (cv != null) {cv.visit(version, access, name, signature, superName, interfaces);}}@Overridepublic MethodVisitor visitMethod(int access,String name,String desc,String signature,String[] exceptions){if (cv != null && "execute".equals(name)) { //当方法名为execute时,修改方法名为execute1return cv.visitMethod(access, name + "1", desc, signature, exceptions);}if("changeMethodContent".equals(name))  //此处的changeMethodContent即为需要修改的方法  ,修改方法內容{  MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);//先得到原始的方法  MethodVisitor newMethod = null;  newMethod = new AsmMethodVisit(mv); //访问需要修改的方法  return newMethod;  }  if (cv != null) {return cv.visitMethod(access, name, desc, signature, exceptions);}return null;}}static  class AsmMethodVisit extends MethodVisitor {public AsmMethodVisit(MethodVisitor mv) {super(Opcodes.ASM4, mv);    }@Overridepublic void visitMethodInsn(int opcode, String owner, String name, String desc) {super.visitMethodInsn(opcode, owner, name, desc);}@Overridepublic void visitCode() {       //此方法在访问方法的头部时被访问到,仅被访问一次//此处可插入新的指令super.visitCode();}@Overridepublic void visitInsn(int opcode) {     //此方法可以获取方法中每一条指令的操作类型,被访问多次//如应在方法结尾处添加新指令,则应判断:if(opcode == Opcodes.RETURN){// pushes the 'out' field (of type PrintStream) of the System classmv.visitFieldInsn(GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;");// pushes the "Hello World!" String constantmv.visitLdcInsn("this is a modify method!");// invokes the 'println' method (defined in the PrintStream class)mv.visitMethodInsn(INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");
//                mv.visitInsn(RETURN);}super.visitInsn(opcode);}}}

输出:

add方法是新增的,execute方法名改为execute1,changeMethodContent方法修改后增加了输出this is a modify method!

public static void AsmExample$Foo.changeMethodContent()
public static void AsmExample$Foo.execute1()
public static void AsmExample$Foo.add(java.lang.String[])
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
*************
test change method
this is a modify method!
*************
test changed method name

我们把最终的字节码保存到文件中e:\\logs\\Example.class中,再用反编译工具java decompiler 查看最终的生成的源码:

最终的类如下:

import java.io.PrintStream;public class AsmExample$Foo
{public static void execute1(){System.out.println("test changed method name");}public static void changeMethodContent() {System.out.println("test change method");System.out.println("this is a modify method!");}public static void add(String[] paramArrayOfString){System.out.println("this is add method print!");}
}

接下来再慢慢研究asm里面对字节码的操作,还有其他框架是如果使用asm的。

转载于:https://www.cnblogs.com/zhwj184/archive/2012/08/13/3027473.html

asm字节码操作 方法的动态修改增加相关推荐

  1. aop 获取方法入参出参_ASM字节码编程 | JavaAgent+ASM字节码插桩采集方法名称及入参和出参结果并记录方法耗时...

    作者:小傅哥 博客:bugstack.cn ❝ 沉淀.分享.成长,让自己和他人都能有所收获! ❞ 一.前言 在我们实际的业务开发到上线的过程中,中间都会经过测试.那么怎么来保证测试质量呢?比如:提交了 ...

  2. 【JVM】字节码与ASM字节码增强、Instrument实现类的动态重加载

    目录 字节码与ASM字节码增强 什么是字节码? 字节码结构 操作数栈与字节码 字节码增强 ASM 运行时类加载 Instrument JPDA与JVMTI instrument实现热加载的过程 字节码 ...

  3. ASM字节码编程 | JavaAgent+ASM字节码插桩采集方法名称以及入参和出参结果并记录方法耗时

    作者:小傅哥 博客:bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在我们实际的业务开发到上线的过程中,中间都会经过测试.那么怎么来保证测试质量呢?比如:提交了多少代码 ...

  4. 注解、反射、动态编译、字节码操作

    注解.反射.动态编译.字节码操作 前言:本篇博客将介绍Java中注解的定义.使用以及反射对Java动态性的支持和Java字节码操作,通过本篇内容,读者将对Java知识有更加深刻的理解,同时为后面And ...

  5. ASM字节码编程 | 用字节码增强技术给所有方法加上TryCatch捕获异常并输出

    作者:小傅哥 博客:https://bugstack.cn Wiki:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有所收 ...

  6. 深入字节码操作:使用ASM和Javassist创建审核日志

    深入字节码操作:使用ASM和Javassist创建审核日志 原文链接:https://blog.newrelic.com/2014/09/29/diving-bytecode-manipulation ...

  7. 菜鸟学习笔记:Java提升篇12(Java动态性2——动态编译、javassist字节码操作)

    菜鸟学习笔记:Java提升篇12(Java动态性2--动态编译.javassist字节码操作) Java的动态编译 通过脚本引擎执行代码 Java字节码操作 JAVAssist的简单使用 常用API ...

  8. 【ASM】字节码操作 ClassWriter COMPUTE_FRAMES 的作用 与 visitMaxs 的关系

    1.概述 看这个首先看文章:[ASM]字节码操作 MethodVisitor 案例实战 调用方法 在创建ClassWriter对象时,使用了ClassWriter.COMPUTE_FRAMES 选项. ...

  9. Java中动态加载字节码的方法 (持续补充)

    文章目录 Java中动态加载字节码的方法 1.利用 URLClassLoader 加载远程class文件 2.利用 ClassLoader#defineClass 直接加载字节码 2.1 类加载 - ...

最新文章

  1. Spring Cloud JWT文件生成
  2. R语言Logistic回归模型案例基于AER包的affair数据分析
  3. 闪迪U3利用工具U3-Pwn
  4. java 实现 DES加密 解密算法
  5. 如何快速搭建开放、多租户的电商云平台
  6. 「开源」首次被列入“十四五”规划,未来大有可为
  7. android camera 实时滤镜,【Camera】Android平台Camera实时滤镜实现方法
  8. Nginx大规模并发原理
  9. JS 打印 data数据_小程序导出数据到excel表
  10. 【译】用 JavaScript 和 Emoji 做地址栏动画
  11. Linux下安装LAMP的步骤
  12. 类库从自带的配置文件中获取信息(DLL文件 获取 DLL文件自带的配置信息) z...
  13. Matlab 2016a 安装及破解教程
  14. 基于python生成手写的笔记
  15. 信息学奥赛与大学计算机课程,为什么要学信息学奥赛(NOIP)
  16. 职业规划 软件开发职业规划的10个建议
  17. 概率分布之二项分布与多项分布
  18. 苹果开发者账号申请的一些事
  19. Android手机屏幕的三种状态
  20. 【audio】耳机插拔/线控按键识别流程

热门文章

  1. LeetCode 2079. 给植物浇水(前缀和)
  2. 流式计算的代表:Storm、Flink、Spark Streaming
  3. LeetCode 1759. 统计同构子字符串的数目
  4. 天池 在线编程 课程表(拓扑排序 + 回溯)
  5. LeetCode 352. 将数据流变为多个不相交区间(map二分查找)
  6. 天池 在线编程 高效作业处理服务(01背包DP)
  7. LeetCode 454. 四数相加 II(哈希)
  8. html5怎么跟安卓交互,html5怎么与android交互
  9. 生活中c语言排序案例,C语言之数字排序-基于冒泡排序法的一些案例(对未知数量的数字进行排序)...
  10. 深度学习在美团的应用