下面三篇文章讲解怎么定义类、方法、变量等说的很详细 明了。
http://alvinqq.iteye.com/blog/940960
http://alvinqq.iteye.com/blog/940965
http://alvinqq.iteye.com/blog/940970
一、如何使用ASM
ASM提供了两套API供使用者使用,一套叫Core API,是基于事件的方式对字节码进行处理;另一套叫Tree API,是基于对象的方式对字节码进行处理。如果你熟悉XML解析,那么实际上Core API就是SAX这种处理模式,而Tree API就是DOM这种处理模式。
二、Core API
使用Core API进行对字节码进行处理一般需要三个部分:
- 一个事件的生产者,用于产生各种事件,通常这会是一个
ClassReader
- 一个事件的消费者,用于消费各种事件,通常这会是一个
ClassWriter
-
若干个事件的过滤器,这些过滤器可以对感兴趣的事件进行过滤来处理,这通常会是一些
ClassVisitor
其处理过程如下图所示:
从文件流中读入一个待处理的Class文件,然后new了ClassReader
,作为事件源,然后new了一个ClassWriter
,作为事件的接收者,还实现了一个ClassVisitor
,这个ClassVisitor
将所有的public方法变成了private的方法。接着通过调用cr.accept
方法来触发事件,通过cw.toByteArray
来拿到处理后的字节码并且输出到文件。
从前面的图可以看出,采用Core API处理字节码,其实就是通过继承ClassVisitor
,并且覆盖ClassVisitor
中的对应的方法来对特定的事件进行处理的过程,其实这里的事件基本上对应到了Class文件中的各个部分,除了常量池部分,所以如果了解了Class文件的结构,那么用Core API处理起来应该得心应手。
除了ClassVisitor
之外,Core API还提供了MethodVisitor
、FieldVisitor
、AnnotationVisitor
来对方法,字段和注解操作。
三、 Tree API
Tree API是基于对象的方式来处理字节码,Tree API的最核心的一个类就是ClassNode
,它就代表了一个Java Class文件,它里面的属性对应到了一个Class文件的各个部分。
ClassNode,用来创建一个继承了java.lang.Runnable
接口的接口ASMInterface
,它包含了一个方法public void stop()
,最后将生成的字节码通过ClassWriter
输出到文件。
和创建类一样,通过Tree API修改一个类也只需要修改ClassNode
的属性。如果你要修改方法,字段或者注解,那么可以通过ClassNode
拿到MethodNode
、FieldNode
、AnnotationNode
来进行对应的修改。
四、什么时候使用Core API,什么时候使用Tree API?
Core API和Tree API其实各有优缺点:
- Core API的优势是处理速度快,占用内存小,因为它不需要在内存中将整个Class文件表示出来,缺点是基于事件的方式处理,如果错过一个事件,那么就是过了这个村,没有这个店了,这样如果需要实现诸如将特定
GOTO
出插入其他指令,就会比较麻烦,因为GOTO
可以跳转到之前的指令,但是之前的指令的事件已经被处理了,到时候只能再次触发一遍事件来处理。
- Tree API的优势就是Core API的劣势,对于上面提到的
GOTO
的这种情况,Tree API处理起来就轻松了很多,因为在内存中有Class文件的完整表示,随便什么样的顺序去改都是没有问题的。缺点就是占用内存比较大,处理速度比较慢。
如果你查看ClassNode
的源代码,那么可以发现ClassNode
事实上继承了ClassVisitor
。那么,我们就可以将在实际操作的时候将Core API和Tree API结合起来,灵活运用各自的优缺点去解决问题。
五、辅助工具类
ASM除了提供了Core API和Tree API两套API以外,还提供了几个比较实用的工具类
CheckClassAdapter
实际上,用ASM生成的字节码可能并不符合Java虚拟机规范的,如果需要检查生成的字节码符不符合规范,那么可以用CheckClassAdapter
作为一个ClassVisitor
加入到ClassVisitor
链中,如果字节码不符合规范,那么CheckClassAdapter
就会抛出异常。
ASMifier
ASM作为一个字节码操作工具,相对于其他的字节码操作工具,比如Javassist,写起来还是比较烦琐的,如果你已经有了一个Class文件,想要知道如何通过ASM生成这个Class文件,那么就可以直接用ASMifier
这个类,通过这个类,可以直接生成出生成目标类的ASM代码,一定程度上简化了直接手写ASM代码的繁琐工作。
ASMifier可以直接通过命令行来使用,比如那我们刚才生成的那个ASMInterface
为例:
可以看到ASMifier
直接将生成ASMInterface
所需要的ASM代码直接打印出来了。
LocalVariableSorter
假设你要往一个方法里面加入一个本地变量,那么你就需要将这个变量加入到本地变量表的最后,遗憾的是,本地变量表的大小只有当你在调用visitMaxs
的时候才知道,通常,这个时候已经到了方法的结尾处,再想加本地变量已经晚了,现在通过LocalVariableSorter
这个ClassVisitor
,你就可以非常简单插入一个本地变量。
转载:http://www.khotyn.com/2012/03/06/asm_note/
- 大小: 53.5 KB
- 大小: 27.4 KB
- 大小: 77 KB
分享到:
相关推荐
Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
它提供了一组工具和类,帮助开发者解析和检查类文件的结构,包括类、方法、字段等元素,以及它们的访问标志和属性。通过这些功能,开发者可以进行代码复杂度分析、性能瓶颈探测,甚至进行安全审计。 ASM库本身的...
"asm-attrs-2.1.jar"可能是一个包含了ASM库对Java类属性处理功能的特定版本。在Java中,类属性包括如源文件名、方法参数的名字、注解等元数据。ASM库提供了访问和修改这些属性的工具,使得开发者可以更深入地控制...
"asm-attrs"部分可能指的是ASM库中处理Java类属性的部分,比如注解(annotations)和其他元数据。在Java字节码中,属性是与类、字段、方法或代码块关联的额外信息。ASM库提供了对这些属性的解析和生成能力,使得...
四、ASM Tree的应用场景 1. 动态代理:ASM Tree常用于动态生成代理类,实现AOP(面向切面编程)功能,如Spring AOP的实现就部分依赖于ASM。 2. 代码混淆:在Android开发中,ProGuard和R8等混淆工具使用ASM Tree来...
动态代理可以利用ASM Tree来快速生成代理类,实现方法拦截;代码生成则可以自动生成符合特定需求的Java类或方法;字节码插桩则是在编译后的字节码层面插入额外的代码,以实现性能监控、调试或者其他高级功能。 在...
ASM库主要用于生成和分析Java字节码,从而提供对Java类和方法的低级别操作。 描述中提到的"asm, attrs, 2.0, jar.zip包下载, 依赖包"表明这个压缩文件与ASM库的Attributes模块有关,该模块可能处理Java类文件中的...
ASM-Attrs-1.5.2.jar.zip文件是ASM库的一个特定版本,包含了对Java类和属性进行深度操作的特性。ASM库以其高度灵活性和低级访问权限,为开发者提供了深入到Java虚拟机(JVM)内部的可能性,从而实现诸如代码混淆、...
2. **ClassReader**:解析已存在的字节码,提供访问类信息的API,包括类的结构、方法、字段和属性。 3. **Visitor**:ASM库采用访问者模式,使得用户可以自定义处理类、方法、字段等的逻辑。例如,`ClassAdapter`和...
2. **字节码分析**:ASM可以解析Java类的字节码,提供对类结构的详细访问,如类、接口、字段、方法、注解等,以及它们的属性。 3. **动态代理**:利用ASM,开发者可以创建动态代理类,实现特定的接口并在运行时拦截...
3. **字节码修改**:在解析类文件后,ASM允许开发者修改这些对象模型,比如添加、删除或修改方法体、字段和类属性。这种能力对于AOP(面向切面编程)和代码增强等场景非常有用。 4. **字节码生成器**:ASM提供了...
Java class 被存储在严格格式定义的 .class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至...
3. **属性处理**:ASM-Attrs.jar 提供了对类、字段、方法等属性的高级操作,包括访问、修改和添加自定义属性。在处理如注解、运行时可见性等元数据时,这一特性尤为重要。 4. **API设计**:ASM的API设计简洁而强大...
"asm-attrs"部分可能指的是ASM库中处理Java类属性的部分,这通常涉及到对类、方法和字段的各种元数据的解析和操作。 描述中提到的标签"asm-attrs-2.2.1.jar.zip, asm, attrs, 2.2.1, jar.zip包下载, 依赖包"进一步...
ASM库的核心功能在于读取和生成Java字节码,而“attrs”部分则专门处理类、字段和方法的属性信息。在Java中,属性是类、字段或方法的附加元数据,例如源文件名、注解信息等。ASM库的这个版本(1.4.1)可能包含了一些...
1. **字节码分析**:ASM可以解析已有的Java字节码,帮助开发者理解类结构,包括类的字段、方法、属性等信息。 2. **字节码生成**:ASM提供API来生成新的Java类或者修改已存在的类,这在动态代理、代码生成、运行时...
5. **元数据支持**:ASM不仅处理字节码,还能够读取和写入类的元数据,例如注解和属性,这对于理解和处理现代Java代码非常重要。 6. **性能与效率**:由于ASM直接操作字节码,因此在生成和修改字节码时具有较高的...
ASM-util进一步扩展了这些功能,提供了一些预定义的工具类,如类访问器、字段访问器和方法访问器等,它们简化了常见的字节码操作任务。 在ASM-util-3.0_RC1.jar中,我们可以通过以下方式使用这些工具: 1. 类访问...
`asm-attrs-1.5.1.jar`是压缩包中的主要文件,它是ASM库的属性处理部分,可能包含了对Java类文件中的注解和属性的处理功能。ASM库通常包含多个组件,如核心库(asm.jar)、访问框架(asm-commons.jar)、树API(asm-...
在Java字节码中,属性是附加到类、方法、字段或其他字节码结构上的元数据。它们提供了关于代码的额外信息,这些信息可能在标准的Java类文件格式中没有定义。ASM库通过提供低级别的访问和修改这些属性的能力,为...