最近复盘了一下java Agent技术,长时间不用就忘了,这里记录一下自己的理解和易错点,加强记忆也给分享给大家
java agent即探针技术,允许在JVM启动时或运行时动态加载,并通过修改字节码来增强或监控Java应用程序的行为
前置准备工作
先写一个简答的app应用,代码如下
public class InstrumentApp {
public void test() {
System.out.println("InstrumentApp.test() ..........");
}
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
// 每隔一秒执行一次
new InstrumentApp().test();
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
}
可执行jar包的maven pom.xml配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<!-- 是否将依赖添加到MANIFEST.MF文件的Class-Path -->
<addClasspath>true</addClasspath>
<!-- 指定Main-Class -->
<mainClass>org.hrj.s.app.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
将这个app打成jar包,通过java -jar启动
D:\test>java -jar hrj-s-app-1.0.0.jar
InstrumentApp.test() ..........
InstrumentApp.test() ..........
InstrumentApp.test() ..........
1. 启动时加载,也叫静态加载
1.1 探针类
在app进程启动时会执行agent中的premain方法,premain方法有个方法,示例如下
// 接收agent的参数,并且可以修改字节码 优先调用此方法,不存在调用另一个,否则报错
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("premain 1 ,agentArgs :"+agentArgs);
}
// 接收agent的参数,只适合打印