本文共 1770 字,大约阅读时间需要 5 分钟。
大家可能已经非常熟悉下面的处理流程:将一个“.java”文件输入到Java编译器中(可能会使用javac,也可能像ANT、Maven或Gradle这样的构建工具),编译器对其进行分析,最终生成一个或多个“.class”文件。
\\ \\图1:什么是Java字节码?
\\如果从命令行中运行构建,并启用verbose的话,我们能够看到解析文件直到生成“.class”文件这一过程的输出。
\\\javac -verbose src/com/example/spring2gx/BankTransactions.java\\ \\
所生成的“.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\
转载地址:http://vicix.baihongyu.com/