ASM开发

233 阅读2分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

ASM就是自己去修改字节码文件来完成一些功能。它是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

cglib spring 等框架都直接或者间接的使用了ASM框架。

ASM的编程模型

ASM的编程模型

  1. core api:基于事件形式的编程模型
    1. 不需要将class文件一次性全部加载到内存,Core是基于访问者模式来操作类
    2. 更快,占用内存更小,但是编程复杂度越高。
    3. 常用的还是coreAPI
  2. tree api:基于树型的编程模型
    1. 需要一次性将class文件加载到内存中
    2. 编程简单,但是内存占用高。

处理方式就类似于xml的解析,可以一个节点一个节点的解析,也可以读取整个dom进行解析。

Core API

这个api主要借助ClassVisitor接口实现功能。ClassVisitor接口的每个方法都对应着class文件的每一块。

ASM提供了三个基于ClassVisitor的实现类来操作class(生成和转换class文件)

ClassReader:读取并解析一个class字节码

classAdapter:将classReader读进来的类,做转变

ClassWriter:输出变化后的字节码

ASM给我们提供了ASMifier工具来帮助我们开发,我们可以使用ASMifier工具类生成ASM结构来对比。

因为ASMcore的开发,我们需要写ASM的一些涉及字节码的东西,这个不好写,所以我们通过ASMifier这个工具,将我们需要增强的代码,和原始代码 通过ASMifiter解析,然后对比下差异代码,即我们需要新增的代码。

demo

在所有执行的方法前后,打印执行时间

  1. 编写原始类
  2. 使用ASMifiter解析下,取出解析的代码
  3. 对原始类修改为自己想要增强的代码。然后ASMIfiter解析下,提取新增的代码块。

image.png

  1. 编写ClassVisitor 实现类

image.png 主要修改visitMethod类

image.png

image.png

image.png

测试:

image.png

我们可以直接就使用CC,因为此时CC会被我们无感知的增强。(不过每次都需要我们将cc先生成增强好了的字节码到bin下面,因为是demo所以只是演示)