JDK提供了一种技术,可以对 应用无任何的代码侵入的情况下,追加某种功能。这种技术是探针
第一点:
通常 我们的项目 中只有一个 main 函数,项目JVM 启动时,会运行 这个main函数。
public static void main( String[] args ) {
}
使用探针时, 探针类 需要有一个 premain函数,比如:
public static void premain(String Args, Instrumentation instrumentation) {
}
第二点:
带有探针类时,通常是单独打成一个 jar包,-javaagent:agent.jar 指定探针jar
java -javaagent:agent.jar -jar app.jar
第三点:
premain 函数 可以执行添加 ClassFileTransformer 对象的操作:
instrumentation.addTransformer(new ClassFileTransformerImpl());
对于 ClassFileTransformer接口,只有一个方法,我们需要实现该接口:
public interface ClassFileTransformer {
byte[]
transform( ClassLoader loader,
String className,
Class> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
throws IllegalClassFormatException;
}
第四点:
对于 premain 函数的执行时机 和 ClassFileTransformer接口 的 transform 函数的执行时机:
JVM启动后,首先会执行 premain函数 并且 只执行一次,随后再执行 main函数。
而 ClassFileTransformer接口 的 transform 函数 ,会在 每次 加载了一个 类时,就执行一次。
这一点很重要,因为 这个方法 能够拿到 当前加载的类信息,那么 就可以对 加载的字节码 等进行操作,来完成 我们的需求。
注意一点:重复实例化一个类, transform函数 只在第一次执行
补充:
探针jar包需要在 META-INF\MANIFEST.MF 中指定
Premain-Class: org.wxj.agent.Agent
应用jar包也需要在 META-INF\MANIFEST.MF 中指定
Main-Class: org.wxj.App
可以在 maven 打包插件指定main函数所在的类:
maven-jar-plugin
3.0.2
false
org.wxj.App
以上就是 java探针的一些知识点。好好看看,来实现第一个探针吧