- 浏览: 741237 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
lgh1992314:
a offset: 26b offset: 24c offse ...
java jvm字节占用空间分析 -
ls0609:
语音实现在线听书http://blog.csdn.net/ls ...
Android 语音输入API使用 -
wangli61289:
http://viralpatel-net-tutorials ...
Android 语音输入API使用 -
zxjlwt:
学习了素人派http://surenpi.com
velocity宏加载顺序 -
tt5753:
谢啦........
Lucene的IndexWriter初始化时的LockObtainFailedException的解决方法
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 class mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // pushes the "Hello World!" String constant mw.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 // variables mw.visitMaxs(0, 0); mw.visitEnd(); // gets the bytecode of the Example class, and loads it dynamically byte[] 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 dynamically FileOutputStream 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); } @Override public 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); } } @Override public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions) { if (cv != null && "execute".equals(name)) { //当方法名为execute时,修改方法名为execute1 return 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); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { super.visitMethodInsn(opcode, owner, name, desc); } @Override public void visitCode() { //此方法在访问方法的头部时被访问到,仅被访问一次 //此处可插入新的指令 super.visitCode(); } @Override public void visitInsn(int opcode) { //此方法可以获取方法中每一条指令的操作类型,被访问多次 //如应在方法结尾处添加新指令,则应判断: if(opcode == Opcodes.RETURN) { // pushes the 'out' field (of type PrintStream) of the System class mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // pushes the "Hello World!" String constant mv.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的。
发表评论
-
对字符串进行验证之前先进行规范化
2013-09-17 23:18 13889对字符串进行验证之前先进行规范化 应用系统中经常对字 ... -
使用telnet连接到基于spring的应用上执行容器中的bean的任意方法
2013-08-08 09:17 1434使用telnet连接到基于spring的应用上执行容器中 ... -
jdk7和8的一些新特性介绍
2013-07-06 16:07 10073更多ppt内容请查看:htt ... -
java对于接口和抽象类的代理实现,不需要有具体实现类
2013-06-12 09:50 2909原文链接:http://www.javaarch.net/j ... -
Excel2007格式分析和XML解析
2013-06-07 09:56 10614在物料清单采购中,用到excel上传文件解析功能,不 ... -
Java EE 7中对WebSocket 1.0的支持
2013-06-05 09:27 3801原文链接:http://www.javaarch.n ... -
java QRCode生成示例
2013-06-05 09:26 1468原文链接:http://www.javaarch.n ... -
Java Web使用swfobject调用flex图表
2013-05-28 19:05 1081Java Web使用swfobject调用 ... -
spring使用PropertyPlaceholderConfigurer扩展来满足不同环境的参数配置
2013-05-21 15:57 3292spring使用PropertyPlaceholderCon ... -
java国际化
2013-05-20 20:57 4439java国际化 本文来自:http://www.j ... -
RSS feeds with Java
2013-05-20 20:52 1186RSS feeds with Java 原文来自:htt ... -
使用ibatis将数据库从oracle迁移到mysql的几个修改点
2013-04-29 10:40 1639我们项目在公司的大战略下需要从oracle ... -
线上机器jvm dump分析脚本
2013-04-19 10:48 2864#!/bin/sh DUMP_PIDS=`p ... -
eclipse远程部署,静态文件实时同步插件
2013-04-06 20:18 5420eclipse 远程文件实时同步,eclipse远程 ... -
java价格处理的一个问题
2013-03-26 21:21 1795我们经常会处理一些价格,比如从运营上传的文件中将某 ... -
java 服务降级开关设计思路
2013-03-23 16:35 3721java 服务屏蔽开关系统,可以手工降级服务,关闭服 ... -
poi解析excel内存溢出
2013-03-20 22:21 6347真是悲剧啊,一个破内部使用系统20多个人使用的后 ... -
简单web安全框架
2013-03-16 11:56 1501web安全框架,主要用servlet filter方 ... -
基于servlet的简单的页面缓存框架
2013-03-11 19:27 1181基于servlet的页面级缓存框架的基本用法: 代码参考: ... -
Eclipse使用过程中出现java.lang.NoClassDefFoundError的解决方案
2013-02-01 17:22 1477如果jdk,classpath设置正确,突然在eclipse ...
相关推荐
一个简单的通过ASM修改字节码实现AOP功能的实例,简单易懂,可运行...
ASM操作字节码,动态生成Java类class文件,模拟Spring的AOP实现原理。
ASM 4 的中文文档 网上的博文都是从这上边摘得,大家下载下来学学就会了,这个是最全的了。我就是通过这个学会的。
ASM是一个java字节码操纵框架,它能被用来动态...asm字节码增强技术主要是用来反射的时候提升性能的,如果单纯用jdk的反射调用,性能是非常低下的,而使用字节码增强技术后反射调用的时间已经基本可以与直接调用相当了
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
Javassist 提供了java类库,用于方便操控Java字节码。功能包括:运行时创建java class,修改class。与其他同类工具(asm等)...通过java代码层,开发者即时对字节码不是很熟悉,也可以非常方便快速的完成字节码的修改。
在ASM中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和灵活的操作字节码的方式。ASM相当小巧,并且它有更高的执行效率,是BCEL的7倍,SERP的11倍以上。目前...
ASM是一个通用的Java字节码操作和分析框架。它可以用于修改现有类或直接以二进制形式动态生成类。ASM提供了一些常见的字节码转换和分析算法,可以从中构建自定义复杂转换和代码分析工具。ASM提供与其他Java字节码...
Java的asm文档,来自官方。asm4-guide.pdf。ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在...说白了asm是直接通过字节码来修改class文件。
ASM是一套java字节码生成架构,它可以动态生成二进制格式的stub类或其它代理类, 或者在类被java虚拟机装入内存之前,动态修改类。 现在挺多流行的框架都使用到了asm.所以从aop追溯来到了这。
这可以通过操作方法的元数据(如方法名、返回类型、参数类型等)和字节码指令来实现。 4. 创建和修改字段:可以在运行时动态创建新的字段,或者修改现有的字段。这可以通过操作字段的元数据(如字段名、类型、修饰符...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
例如,可以使用ASM Tree API遍历一个类的整个字节码结构,查找并修改特定的指令或属性,或者在运行时动态生成新的类和方法。此外,由于ASM Tree API具有较高的抽象层次,因此它适用于各种类型的Java字节码操作,无论...
asmsupport是一个字节码操作类库,它能够让程序员非常简单的在动态创建和修改类,该框架是基于asm开发的,不同与asm的是,它避免了直接操作jvm指令,栈和局部变量。这个模块包含了asmsupport使用的第三方依赖包的...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class文件...
ASM是一个通用的Java字节码操作和分析框架。 它可以用于修改现有类或直接以二进制形式动态生成类。 ASM提供了一些常见的字节码转换和分析算法,可以从中构建自定义复杂转换和代码分析工具。 ASM提供与其他Java字节码...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
AsmTools项目是一个字节码分析和测试工具,用来生成正确的或者不正确的java .class文件,主要用来测试和验证。 我们知道直接修改.class文件是很麻烦的,虽然有一些图形界面的工具,但还是很麻烦。 通过ASMTools可以...