一、字节码是什么
Java程序都是跑在JVM上的,我们日常所编写的 java文件需要先编译为.class文件然后才可以被类加载器加载后进入到JVM中,被正确识别后才能运行,而这个.class文件里的内容就是我们今天要说的字节码。
我们可以通过命令:javap -verbose + 类名 查看字节码内容,如下:
二、实现思路
我们先看一张流程图:
我们手工编写 Java 文件,然后编译成 .class文件,最终通过类加载器将类加载进 JVM。如果我们不想更改源码,但是又想对程序做一些修改,让程序按照我们预期去运行,那么我们可以在上图中的编译和加载这两个步骤去进行,即:如果我们可以把.class文件的内容改成我们所需要的,我们的预期就得以实现了。
三、应用场景
1、流量回放
我们可以在程序的入口处,修改入口处的字节码,增加流量进入时的存储逻辑,当流量进来时,就可以按照我们自己的格式和要求将流量落地,进而给后续的回放提供支撑.有些团队会选择在代码中加注解来识别,比如基于Spring的aop或cglib来达到这种效果,但是这样会对代码有一定的侵入性.个人感觉不如原生字节码注入好.
2、各类开关
我们经常会有一些需求比如线上线下环境要实现不同的逻辑处理,如调用第三方接口有验签或加密时,可能为了线下的mock方便就会加各种开关来关闭掉,此时其实我们就可以使用字节码技术来做到不修改源代码逻辑,随意控制开关的有无.
3、异常代码注入
现在有一个比较好玩的技术叫混沌工程,几年前有一些说法叫故障演练,在注入故障时,除了系统级的故障外,其实我们也可以模拟一些代码级的故障,比如各种异常返回,抛出异常,方法执行超时等等.那么这些随机的,各种异常的代码故障,都可以应用字节码修改的手段来完成.目前这块也有比较成熟的框架供使用,后续会有介绍
四、JVMTI
五、类库支持
当前主要有大神级的ASM, 以及大侠级的 javassist,其他也有一些,不过多是基于ASM做的各种二次开发和扩展来的。我们的演示将会以 javassist来展开,这款框架主要是简单,上手快,可以快速出结果。
六、agent演示
原文:https://www.cnblogs.com/L-Test/p/12447974.html