字节码插桩
我们知道JVM是不能直接执行.java 代码,也不能直接执行.class文件,它只能执行.class 文件中存储的指令码。这就是为什么class需要通过classLoader 装载以后才能运行。基于此机制可否在ClassLoader装载之前拦截修改class当中的内容(jvm 指令码)从而让程序中包含我们的埋点逻辑呢?答案是肯定的,但需要用到两个技术 javaagent与javassist 。前者用于拦截ClassLoad装载,后者用于操作修改class文件。
javaagent
javaagent介绍
javaagent 是java1.5之后引入的特性,其主要作用是在class 被加载之前对其拦截,以插入我们的监听字节码
javaagent jar包
javaagent 最后展现形式是一个Jar包,有以下特性:
1.必须 META-INF/MANIFEST.MF中指定Premain-Class 设定启agent启动类。
2.在启类需写明启动方法 public static void main(String arg,)
3.不可直接运行,只能通过 jvm 参数-javaagent:xxx.jar 附着于其它jvm 进程运行。
javaagent使用
1、编写agent方法
public class MyAgent {
public static void premain(String args, Instrumentation instrumentation) throws Exception {
System.out.println("Hello javaagent permain:"+args);
}
}
2、添加premain-class参数
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifestEntries>
<Project-name>${project.name}</Project-name>
<Project-version>${project.version}</Project-version>
<Premain-Class>com.javaagent.MyAgent</Premain-Class>
<Can-Redefin