字节码操纵技术探秘

大家可能已经非常熟悉下面的处理流程:将一个“.java”文件输入到Java编译器中(可能会使用javac,也可能像ANT、Maven或Gradle这样的构建工具),编译器对其进行分析,最终生成一个或多个“.class”文件。

\\

b6affe4f945219825931250e8e68a5a3.jpg

\\

图1:什么是Java字节码?

\\

如果从命令行中运行构建,并启用verbose的话,我们能够看到解析文件直到生成“.class”文件这一过程的输出。

\\
\javac -verbose src/com/example/spring2gx/BankTransactions.java
\\

3dca5c7115bb78403ae31223a57bf3c8.jpg

\\

所生成的“.class”文件包含了字节码,本质上来讲它就是Java虚拟机(Java virtual machine,JVM)所使用的指令,当程序运行时,它会由Java运行时类加载器进行加载。

\\

在本文中,我们将会研究Java字节码以及如何对其进行操纵,并探讨人们为何想要这样做。

\\

字节码操纵框架

\\

最为流行的字节码操纵框架包括:

\\

本文将会主要关注Javassist和ASM。

\\

我们为什么应该关注字节码操纵呢?

\\

很多常用的Java库,如Spring和Hibernate,以及大多数的JVM语言甚至我们的IDE,都用到了字节码操纵框架。另外,它也确实非常有趣,所以这是一项很有价值的技术,掌握它之后,我们就能完成一些靠其他技术很难实现或无法完成的任务。一旦学会之后,我们的发挥空间将是无限的!

\\

一个很重要的使用场景就是程序分析。例如,流行的bug定位工具FindBugs在底层就使用了ASM来分析字节码并定位bug。有一些软件商店会有一定的代码复杂性规则,比如方法中if/else语句的最大数量以及方法的最大长度。静态分析工具会分析我们的字节码来确定代码的复杂性。

\\

另外一个常见的使用场景就是类生成功能。例如,ORM框架一般都会基于我们的类定义使用代理的机制。或者,在考虑实现应用的安全性时,可能会提供一种语法来添加授权的注解。在这样的场景下,都能很好地运用字节码操纵技术。

\\

像Scala、Groovy和Grails这样的JVM语言都使用了字节码操纵框架。

\\

考虑这样一种场景,我们需要转换库中的类,这些类我们并没有源码,这样的任务通常会由Java profiler来执行。例如,在New Relic,采用了字节码instrumentation技术实现了对方法执行的计时。

\\

借助字节码操纵,我们可以优化或混淆代码,甚至可以引入一些功能,比如为应用添加重要的日志。本文将会关注一个日志样例,这个样例提供使用这些字节码操纵框架的基本工具。

\\

我们的样例

\\

Sue负责一家银行的ATM编程,她有了一项新的需求:针对一些指定的重要操作,在日志中添加关键的数据。

\\

如下是一个简化的银行交易类,它允许用户通过用户名和密码进行登录、进行一些处理、提取一些钱,然后打印“交易完成”。这里的重要操作就是登录和提款。

\\
\public void login(String password, String accountId, String userName) { \// 登录逻辑 \} \public void withdraw(String accountId, Double moneyToRemove) { \// 交易逻辑 \}
\\

为了简化编码,Sue会为这些方法调用创建一个@ImportantLog注解,这个注解所包含的输入参数代表了希望记录的方法参数索引。借助这一点,她就可以为login和withdraw方法添加注解了。

\\
\/** \* 方法注解,用于识别 \* 重要的方法,这些方法的调用需要进行日志记录。 \*/ \public @interface ImportantLog { \/** \* 需要进行日志记录的方法参数索引。 \* 例如,如果有名为 \* hello(int paramA, int paramB, int paramC)的方法,我们 \* 希望以日志的形式记录paramA和paramC的值,那么fields \* 应该是[\"0\
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值