一、背景说明
javaAgent技术,在运行方法之前运行的拦截器,通过JVM加载class二进制文件的时候,利用ASM动态的修改加载的class字节码文件,在监控方法前后进行统一处理。可以粗略理解为使用字节码方式完成的功能切面。常用于监控方法耗时、调用次数等功能。
javaAgent程序以jar包方式供业务功能代码使用,通过添加 VM options方式动态指定javaAgent程序功能业务功能使用。
详见:https://www.jianshu.com/p/3bd123915216
二、javaagent jar包使用
新建MyTest类,其中MyTest代码如下所示:
public class MyTest {
public static void main(String[] args) {
System.out.println("Main测试开始");
}
}
运行MyTest类中的main方法,在idea中对main方法Run进行配置,具体配置如下所示:
-javaagent:D:\work\my-agent-1.1.0.jar
在idea中配置VM options 如下图所示:
运行MyTest-main方法,运行结果如下所示:
LocalProgram 开始运行 Main测试开始
三、开发并编译javaagent my-agent.jar包
新建maven项目my-agent,并编写javaagent 程序代码,如下所示:
import java.lang.instrument.Instrumentation;
public class LocalProgram {
public static void premain(String agentOps,Instrumentation instrumentation){
System.out.print("LocalProgram 开始运行");
//添加字节码 变更规则 自定义动态改变字节码文件改变规则
//instrumentation.addTransformer(new MyTransformer());
}
public static void premain(String agentOps){
System.out.print("LocalProgram 开始运行,参数:"+agentOps);
//添加字节码 变更规则 自定义动态改变字节码文件改变规则
//instrumentation.addTransformer(new MyTransformer());
}
}
Maven打包配置,如下所示:
.....
org.apache.maven.plugins
maven-jar-plugin
2.6
com.timerbin.LocalProgram
.....
执行Maven 打包命令 mvn install,对javaagent程序进行编译打包,并对编译后的jar包内容进行检查,查看生成jar包内的\META-INF\MANIFEST.MF 文件,文件内容如下所示:
Manifest-Version: 1.0
premain-class: com.timerbin.LocalProgram
Archiver-Version: Plexus Archiver
Built-By: xxxxx
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_151
注:1、每个配置项和值之间的冒号后面紧跟一个空格
2、最后一行一定要为空行
3、一定要包含premain-class 配置项
四、常见问题
1、如何向my-agent.jar 中传递参数?
-javaagent:D:\work\my-agent-1.1.0.jar=测试123
可以在定义VM Options时,在.jar后面直接加参数,就可以将自定义参数传输给 premain方法的agentOps参数。
2、如果我需要定义Transform时,自定义字节码变更规则时,需要使用到log4j 或者其他第三开源包时该怎么办?
.....
org.apache.maven.plugins
maven-jar-plugin
2.6
com.timerbin.LocalProgram
../slf4j-api-1.7.25.jar
.....
可以借助Boot-Class-Path 标签在preMain加载之前加载第三方jar包,支持绝对路径和相对路径,此时slf4j-api-1.7.25.jar jar和pom文件放在同目录。