JDK提供了一种技术,可以对 应用无任何的代码侵入的情况下,追加某种功能。这种技术是探针
第一点:
通常 我们的项目 中只有一个 main 函数,项目JVM 启动时,会运行 这个main函数。
public static void main( String[] args ) {
}
使用探针时, 探针类 需要有一个 premain函数,比如:
public static void premain(String Args, Instrumentation instrumentation) {
}
第二点:
带有探针类时,通常是单独打成一个 jar包,-javaagent: 指定探针jar
java -javaagent: -jar
第三点:
premain 函数 可以执行添加 ClassFileTransformer 对象的操作:
(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\ 中指定
Premain-Class:
应用jar包也需要在 META-INF\ 中指定
Main-Class:
可以在 maven 打包插件指定main函数所在的类:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<mainClass></mainClass>
</manifest>
</archive>
</configuration>
</plugin>
以上就是 java探针的一些知识点。好好看看,来实现第一个探针吧