一:什么是JavaAgent
JavaAgent顾名思义就是Java探针技术,我理解的是,通过一个JavaAgent探针类,可以在java虚拟机启动之前,或者运行的时候植入这个探针类,对jvm做一些特别的操作,如动态改变字节码文件这种,要想植入,肯定是通过jvm参数来搞了
使用JavaAgent的技术的项目我目前知道的是SkyWalking,dubbo用没用我没印象了
二:JavaAgent在JVM运行启动的时候,做一些操作
1.创建一个Java项目,Pure Java Project Only Main method,文件结构如下:
AgentDemoDoMain.Java:
package com.shi;
/**
* @author DaTou
* @Description
* @Date 2020/9/21
**/
public class AgentDemoDoMain {
public static void main(String[] args) {
Test test = new Test();
new Thread(()->{
while (true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.printTest();
}
}).start();
}
}
Test.java:
package com.shi;
/**
* @author DaTou
* @Description
* @Date 2020/9/21
**/
public class AgentDemoDoMain {
public static void main(String[] args) {
Test test = new Test();
new Thread(()->{
while (true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.printTest();
}
}).start();
}
}
2.创建一个JavaAgent项目,代码结构如下:
AgentDemo.java--探针代码:
**其实探针代码是很普通的一个方法,真正需要注意的是MANIFEST.MF文件的配置,项目结构是使用的maven,所以pom的配置对MANIFEST.MF的生成至关重要
package com.shi;
import java.lang.instrument.Instrumentation;
/**
* @author DaTou
* @Description
* @Date 2020/9/21
**/
public class AgentDemo {
/**
* java-agent 静态载入的情况
* @param agentOps
* @param instrumentation
*/
public static void premain(String agentOps, Instrumentation instrumentation) {
System.out.println("====premain method====");
}
}
MANIFEST.MF
Manifest-Version: 1.0
Premain-Class: com.shi.AgentDemo
POM.XML:pom的关键是在对maven打包插件的管理上,要说明自己写的MANIFEST.MF文件的位置,maven打包的时候将会忽略这个文件,生成自己的MANIFEST.MF文件
4.0.0
com.shi
agent-demo
1.0-SNAPSHOT
org.apache.maven.plugins
maven-jar-plugin
src/main/resources/META-INF/MANIFEST.MF
3.运行项目:
运行AgentDemoDoMain.java中的main方法,加入虚拟机参数(xxxx就是探针包的位置):
-javaagent:xxxxx\agent-demo-1.0-SNAPSHOT.jar
4.结束,本次记录的是java探针技术静态插入的demo,没有很复杂,不涉及对类字节码文件的修改,利用java探针结合字节码的一些工具类如javaassit,可以改变编译后的class文件,实现自己想要的功能,但是javaassit我不会,说白了就是运行了两个main方法而已,一个main一个premain