在学习跟介绍ASM框架之前,需要先清楚他出现的一些背景跟目的。
我们先来看下这几个概念:
程序分析: 可以进行简单的语法分析,也可以进行完整的语义分析,可用于查找应用程序中潜在的bug、检测未被用到的代码,等等。
程序生成,这个技术主要在编译器中使用。
程序转换, 这个技术可以用于优化或者重写程序,可以向应用程序中插入调试代码或者性能监视代码,用于面向方面编程的设计。
上面的这些技术都可以针对任何程序语言使用,对于java语言来说,他们可以用于java源代码或者编译后的java类。使用已编译的类还有这个好处:
我们可以在运行时,在类要加载到java虚拟机之前,进行语义分析、生成以及转换。
介绍完了前面的知道,再来讲讲ASM。程序员针对众多开发程序语言实现了很多进行分析和转换程序的工具,这些语言也包括了JAVA在内,而ASM就是实现的工具。进行程序分析、生成以及转换。他主要就是处理经过了编译的类。
总结: ASM使用的目的就是生成、转换、分析以字节数组表示的已编译的JAVA类(因为他们在磁盘中的存储和在虚拟机中加载都采用这种字节数组的形式)
(ASM 提供了一些工具,使用高于 字 节级别的概念来读写和转换这种字节数组,这些概念包括数值常数、字符串、Java 标识符、Java 类型、Java 类结构元素,等等。注意,ASM 库的范围严格限制于类的读、写、转换和分析。具 体来说,类的加载过程就超出了它的范围之外。)
ASM框架设计特点
小型化和快速: 保证减少应用程序的影响和速度,因为其也是运行在内存中的。
使用简单,文档也很齐全。
下载
ASM的两种模型
ASM提供了两种模型来用于生成和转换已编译类的API:
- 核心API,基于event的方式。
- 树API,基于对象的形式。
区别
采用基于事件的模型,类是使用一系列事件来表示,每个事件表示类的一个元素,比如它的一个标头,方法声明,指令等等,他定义了一组可能事件以及这个事件发生必须遵循的顺序,怎么理解呢?
就比如我们普通的一个HelloWorld类,转化为字节码后如下图所示:
我们使用基于事件的方式描述,就需要设置上图右边的结构,每个字段都当作一个事件,来展示其应该出现的顺序,以及可能出现的发生顺序。
采用基于对象的模型,类会用一个对象树来表示,每个对象表示类的一部分,比如类本身,一个字段,一个方法、指令,这些都会使用对象来表示,每个对象都有引用来指向组成部分的对象。
关联: 这两种模型都提供了转换的方法。基于对象的API提拱了一种方法,可以将表示一个类的事件序列转化为表示同一个类的对象树,也可以反过来。
记住: 基于对象的API构建在基于事件的API之上。
为什么要提供这两种?
因为两者之间各有优缺点,互补。可以选择自己所需要的去构建。
基于事件的 API 要快于基于对象的 API,所需要的内存也较少,因为它不需要在内 存中 创建和存储用于表示类的对象树(SAX 与 DOM 之间也有同样的差异)。 但在使用基于事件的 API 时,类转换的实现可能要更难一些,因为在任意给定时 刻, 类中只有一个元素可供使用(也就是与当前事件对应的元素),而在使用基于对 象的 API 时,可以在内存中获得整个类。
(注意,这两个 API 都是仅能同时维护一个类,而且独立于其他类,也就是说,它们不会维 护有关类层级结构的信息,如果类的转换影响到其他类,那其他这些类的修改应当由用户负责完 成。)
结构
ASM 应用程序拥有一个很强壮的体系结构方面(aspect)。
对于基于事件
组织结构会围绕事件生成器(类分析器)、事件使用器(类写入器)和各种预定义的事件筛选器进行,在这一结构中可以添加用户定义的生成器、使用器和筛选器。
使用步骤:
- 将事件生成器、筛选器和使用器组件组装为可能很复杂的体系结构
- 启动事件生成器、以执行生成或转换过程。
基于对象
基于对象的api也有一个体系结构方面,实际上,用于操作类树的类生成器或转换器组件是可以组成的,他们之间的链接代表着转换的顺序。
如下所示的复杂体系结构,其中的箭头表示在类分析器、写入器或转换器之间进行的基于事件或 基于 对象的通信,在整个链中的任何位置,都可能会在基于事件与基于对象的表示之间进行转换:
核心包的作用
ASM 库划分为几个包,以几个 jar 文件的形式进行分发:
org.objectweb.asm 和 org.objectweb.asm.signature 包定义了基于事件的 API,并提供了类分析器和写入器组件。它们包含在 asm.jar 存档文件中。
org.objectweb.asm.util 包,位于 asm-util.jar 存档文件中,提供各种基于核心 API 的工具,可以在开发和调试 ASM 应用程序时使用。
org.objectweb.asm.commons 包提供了几个很有用的预定义类转换器,它们大 多 是基于核心 API 的。这个包包含在 asm-commons.jar 存档文件中。
org.objectweb.asm.tree 包,位于 asm-tree.jar 存档文件中,定义了基于对 象的 API,并提供了一些工具,用于在基于事件和基于对象的表示方法之间进行转换。
org.objectweb.asm.tree.analysis 包提供了一个类分析框架和几个预定义的 类 分析器,它们以树 API 为基础。这个包包含在 asm-analysis.jar 存档文件中。
《ASM手册中文版》阅读笔记
网友评论