博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字节码操纵技术探秘
阅读量:5879 次
发布时间:2019-06-19

本文共 1770 字,大约阅读时间需要 5 分钟。

大家可能已经非常熟悉下面的处理流程:将一个“.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字节码以及如何对其进行操纵,并探讨人们为何想要这样做。

\\

字节码操纵框架

\\

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

\\
  • \\t
  • \\t
  • \\t
  • \\t
  • \\t
  • \\t
  • \\t
  • \

本文将会主要关注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/

你可能感兴趣的文章
form表单下的button按钮会自动提交表单的问题
查看>>
springBoot介绍
查看>>
Intellij IDEA 快捷键整理
查看>>
Redis 通用操作2
查看>>
11. Spring Boot JPA 连接数据库
查看>>
洛谷P2925 [USACO08DEC]干草出售Hay For Sale
查看>>
MapReduce工作原理流程简介
查看>>
那些年追过的......写过的技术博客
查看>>
小米手机解锁bootload教程及常见问题
查看>>
Python内置函数property()使用实例
查看>>
Spring MVC NoClassDefFoundError 问题的解决方法。
查看>>
CentOS 6.9配置网卡IP/网关/DNS命令详细介绍及一些常用网络配置命令(转)
查看>>
python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列
查看>>
C# 解决窗体闪烁
查看>>
CSS魔法堂:Transition就这么好玩
查看>>
【OpenStack】network相关知识学习
查看>>
centos 7下独立的python 2.7环境安装
查看>>
[日常] 算法-单链表的创建
查看>>
前端工程化系列[01]-Bower包管理工具的使用
查看>>
使用 maven 自动将源码打包并发布
查看>>