java agent 可以在main 方法前 添加一个拦截器 ,即premain方法,可以在该方法内执行一些逻辑,需注意在meta-inf/manifest 文件中注明;1.6之后,提供了在JVM运行时,进行代理的方法,即 agentMain方法。
premain方法或agentMain方法中含有 instrumention 参数, Instumention 依赖于 JVMTI。JVMTI(Java Virtual Machine Tool Interface)是一套由 Java 虚拟机提供的,为 JVM 相关的工具提供的本地编程接口集合。JVMTI 是从 Java SE 5 开始引入,整合和取代了以前使用的 Java Virtual Machine Profiler Interface (JVMPI) 和 the Java Virtual Machine Debug Interface (JVMDI),而在 Java SE 6 中,JVMPI 和 JVMDI 已经消失了。JVMTI 提供了一套”代理”程序机制,可以支持第三方工具程序以代理的方式连接和访问 JVM,并利用 JVMTI 提供的丰富的编程接口,完成很多跟 JVM 相关的功能。事实上,java.lang.instrument 包的实现,也就是基于这种机制的:在 Instrumentation 的实现当中,存在一个 JVMTI 的代理程序,通过调用 JVMTI 当中 Java 类相关的函数来完成 Java 类的动态操作。除开 Instrumentation 功能外,JVMTI 还在虚拟机内存管理,线程控制,方法和变量操作等等方面提供了大量有价值的函数。
实现 ClassFileTransFormer 接口 可以达到动态修改类文件的目的,但是实现接口的类还需要javaassist的协助,才能完成对字节码的修改。
在运行时启动agent代理程序,还需要 JAVA attach api 的协助,即ATTACH机制,实质上是 java进程间的通信方式,可以通过一个java 进程向另一个java进程发送命令,达到目的。