特性
在类的字节码载入JVM前会调用ClassFileTransformer的transform方法,从而实现修改原类方法的功能。
原理
JVMTI(Java Virtual Machine Tool Interface)是一套本地编程接口集合,它提供了一套『代理』机制,可以支持第三方工具程序以代理的方式连接和访问 JVM,并利用 JVMTI 提供的丰富的编程接口,完成很多跟 JVM 相关的功能。
java.lang.instrument 包的实现,也就是基于这种机制的:在 Instrumentation 的实现当中,存在一个 JVMTI 的代理程序,通过调用 JVMTI 当中 Java 类相关的函数来完成 Java 类的动态操作。
Instrumentation 的最大作用就是类定义的动态改变和操作。在 Java SE 5 及其后续版本当中,开发者可以在一个普通 Java 程序(带有 main 函数的 Java 类)运行时,通过 – javaagent 参数指定一个特定的 jar 文件(包含 Instrumentation 代理)来启动 Instrumentation 的代理程序。
要素
Premain-Class
打成jar包,在jar包里面的 META-INF/MAINIFEST.MF 必须包含 Premain-Class这个属性。
如果 JVM 启动时指定了代理,那么此属性是必需的,即包含 premain 方法的类。如果该属性不存在,那么 JVM 将中止。
Agent-Class
如果实现支持 VM 启动之后某一时刻启动代理的机制,那么此属性指定代理类。 即包含 agentmain 方法的类。
Boot-Class-Path
设置引导类加载器搜索的路径列表。路径表示目录或库(在许多平台上通常作为 JAR 或 zip 库被引用)。
Can-Redefine-Classes
布尔值(true 或 false,与大小写无关)。是否能重定义此代理所需的类。true 以外的值均被视为 false。此属性是可选的,默认值为 false。
Can-Retransform-Classes
布尔值(true 或 false,与大小写无关)。是否能重转换此代理所需的类。true 以外的值均被视为 false。此属性是可选的,默认值为 false。
Can-Set-Native-Method-Prefix
布尔值(true 或 false,与大小写无关)。是否能设置此代理所需的本机方法前缀。true 以外的值均被视为 false。此属性是可选的,默认值为 false。
实例
import java.lang.instrument.Instrumentation;
public class MyAgent {
public static void premain(String agentOps, Instrumentation inst){
System.out.println(agentOps);
}
}
运行
java -javaagent:myagent.jar=youragrs -jar demo.jar
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。