ASM 系列详细教程-02-ASM 整体概览

动机

程序分析,生成和转换是有用的技术,可以在许多情况下使用:

程序分析

范围从简单的语法分析到完整的语义分析,可用于查找应用程序中的潜在错误,检测未使用的代码,反向工程代码等。

在编译器中使用程序生成。

其中包括传统的编译器,还有用于分布式编程的存根或骨架编译器,即时编译器等

程序转换可用于优化或混淆程序,

将调试或性能监控代码插入应用程序,用于面向方面的编程等

所有这些技术都可以用于任何编程语言,但这或多或少容易实现,具体取决于语言。

对于Java,它们可以在Java源代码或已编译的Java类上使用。

处理已编译类的优点之一是,显然,不需要源代码。

因此,程序转换可用于任何应用程序,包括封闭源代码和商业应用程序。

处理已编译代码的另一个优点是,可以在将类加载到Java虚拟机中之前在运行时分析,生成或转换类(可以在运行时生成和编译源代码,但这确实很慢,并且需要完整的Java编译器)。

优点是存根编译器(stub compilers)或Aspect Weaver等工具对用户透明。

由于程序分析,生成和转换技术的许多可能用法,因此已经为许多语言(包括Java)实现了许多用于分析,生成和转换程序的工具。

ASM 的作用

ASM是Java语言的其中一种工具,旨在用于运行时(但也可以脱机)类生成和转换。

因此,ASM库被设计为在编译的Java类上工作。

尽可能的小

它还被设计为尽可能快和尽可能小。

为了不减慢速度,尽可能快是很重要的在运行时使用ASM进行动态类生成或转换的应用程序过多。

为了在内存受限的环境中使用,并避免过大的膨胀,尽可能地小非常重要。

使用ASM的小型应用程序或库的大小。

其他作用

ASM不是生成和转换已编译Java的唯一工具类,但是它是最新且有效的类之一。

可以下载来自http://asm.objectweb.org。

其主要优点如下:

它具有简单易用,设计良好的模块化API。

  • 有据可查,并且具有关联的Eclipse插件。

  • 它支持最新的Java版本Java 7。

  • 它体积小,速度快并且非常坚固。

  • 其庞大的用户社区可以为新用户提供支持。

  • 其开源许可证允许您以几乎任何所需的方式使用它。

概览

Scope

ASM库的目标是生成,转换和分析以字节数组表示的已编译Java类(因为它们存储在磁盘上并已加载到Java虚拟机中)。

为此,ASM提供了使用比字节更高的概念来读取,写入和转换此类字节数组的工具,例如数字常量,字符串,Java标识符,Java类型,Java类
结构元素等

请注意,ASM库的范围严格限于读取,编写,转换和分析类。

特别是,类加载过程超出了范围。

Model

ASM库提供了两个用于生成和转换已编译类的API:

核心API提供基于事件的类表示,而树API提供基于对象的表示。

在基于事件的模型中,一个类由一系列事件表示,每个事件代表该类的元素,例如其标题,字段,方法声明,指令等。

基于事件的API定义了可能的事件集以及它们必须发生的顺序,并提供了一个类解析器,该类解析器为每个被解析的元素生成一个事件,以及一个类编写器,从这些事件的序列中生成已编译的类。

在基于对象的模型中,用对象树表示一个类,每个对象代表该类的一部分,例如类本身,字段,方法,指令等,每个对象都具有对这些对象的引用。 代表其成分。

基于对象的API提供了一种将表示类的事件序列转换为表示对象的对象树的方法。

相同的类,反之亦然,将对象树转换为等效的事件序列。

换句话说,基于对象的API建立在事件之上基于API。

二者的关系

这两个API可以与XML文档的简单API(SAX)和文档对象模型(DOM)API进行比较:

基于事件的API与SAX相似,而基于对象的API与DOM类似。

基于对象的API建立在基于事件的API之上,就像可以在SAX之上提供DOM一样。

ASM提供这两种API,因为没有最佳的API。

优缺点

实际上,每个API都有自己的优点和缺点:

与基于对象的API相比,基于事件的API更快,并且所需的内存更少,因为不需要创建并在内存中存储代表该类的对象树(SAX和DOM之间也存在相同的区别)。

但是,使用基于事件的API来实现类转换可能会更加困难,因为在任何给定时间只有该类的一个元素(与当前事件相对应的元素)才可用,而整个类都可以在基于对象的内存中使用 API。

请注意,这两个API一次仅管理一个类,而与其他API无关:

不维护有关类层次结构的信息,并且如果类转换影响其他类,则由用户决定是否修改这些其他类。

Architecture

ASM应用程序具有强大的体系结构方面。

实际上,基于事件的API是围绕事件生成器(类解析器),事件使用者(类编写器)和各种预定义的事件过滤器组织的,可以向其中添加用户定义的生产者,使用者和过滤器。

因此,使用此API分为两个步骤:

(1)将事件产生器,过滤器和使用者组件组装成可能复杂的架构,

(2)然后启动事件生产者以运行生成或转换过程。

基于对象的API也具有体系结构方面:

确实可以构成对对象树进行操作的类生成器或转换器组件,它们之间的链接表示转换的顺序。

image

组织信息

ASM库组织在几个软件包中,这些软件包分布在多个jar文件:

  • org.objectweb.asm和org.objectweb.asm.signature

包定义基于事件的API,并提供类解析器和编写器组件。

它们包含在asm.jar存档中。

asm-util.jar存档中的org.objectweb.asm.util包,提供了基于核心API的各种工具,这些工具可以在ASM应用程序的开发和调试。

  • org.objectweb.asm.commons

包提供了几个有用的预定义类转换器,主要基于核心API。

它包含在asm-commons.jar存档中。

  • asm-tree.jar

存档中的org.objectweb.asm.tree包,定义基于对象的API,并提供在基于事件和基于对象的表示形式。

  • org.objectweb.asm.tree.analysis

包提供类分析框架和几个基于树的预定义类分析器API。

它包含在asm-analysis.jar存档中。

文档划分

本文档分为两部分。

第一部分介绍了核心API,即asm,asm-util和asm-commons存档。 第二部分介绍了树API,即asm-tree和asm-analysis存档。

每一部分至少包含一章与类相关的API,一章与方法相关的API,以及一章与注释,泛型等相关的API。

每章均涵盖编程接口以及相关工具和预定义的组件。

所有示例的源代码都可以在ASM网站上找到。

这种组织结构使逐步引入类文件功能变得容易,但有时需要将单个ASM类的表示形式分散在几个部分中。

因此,建议按顺序阅读本文档。

整体时序图

整体时序图

AOP 技术对比

AOP 底层技术功能性能面向接口编程编程难度
直接改写 class 文件完全控制类无明显性能代价不要求 高,要求对 class 文件结构和 Java 字节码有深刻了解
JDK Instrument完全控制类无论是否改写,每个类装入时都要执行 hook程序 不要求 高,要求对 class 文件结构和 Java 字节码有深刻了解
JDK Proxy只能改写 method反射引入性能代价要求 低
ASM几乎能完全控制类无明显性能代价不要求 中,能操纵需要改写部分的 Java 字节码

拓展阅读

更多技术文章,生活趣事,尽在【老马啸西风】。

老马啸西风

参考文档

https://asm.ow2.io/asm4-guide.pdf

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值