概述
- javaagent 技术广泛应用于对代码的增强,比如统计方法执行时间、GC 信息打印、分布式链路跟踪等;
- 实现方式包括 javassist 和 bytebuddy,bytebuddy 是对 javassist 的改进;
- 类似于 spring 中的 AOP;
Instrumentation 实现对 main 方法增强
说明:
- 新建两个项目,一个打包成增强 jar 包,一个写待增强业务代码;
- 可通过定义注解进行优化;
- 注意 maven 打包插件;
1)新建一个 maven 项目,引入 pom 依赖,并指定增强类:
bash
<dependencies>
<!-- javaagent -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
<type>jar</type>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 测试javaagent相关 -->
<plugin>
<!-- 打普通的jar包 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 打包配置 -->
<archive>
<manifestEntries>
<Project-name>${project.name}</Project-name>
<Project-version>${project.version}</Project-version>
<!-- main方法之前需要处理的类 -->
<Premain-Class>com.firechou.test.javaagent.FireAgent</Premain-Class>
</manifestEntries>
</archive>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
注意插件中 Premain-Class 指定的是增强类。
2)新建代理类,编写增强逻辑
java
public class FireAgent {
/**
* 在Instrumentation中有对应的说明:当jvm以代理类的方式启动时,Instrumentation的实例将传递给premain方法
* @param args
* @param instrumentation
*/
public static void premain(String args, Instrumentation instrumentation){
System.out.println("agent premain(), args: " + args);
}
}
3) 打包成 jar
执行打包命令:
注意:不要执行 Plugins》jar》jar:jar 命令,会提示找不到目标类。
生成增强 jar 包如下:
4)在另一个项目中,新建业务代码类,即被增强的逻辑
java
public class FireAgentMainTest {
public static void main(String[] args) {
System.out.println("hello world");
}
}
添加 JVM 运行参数:
bash
-javaagent:test-javaagent/target/test-javaagent-1.0-SNAPSHOT.jar=name=jar&age=33
运行结果:
bash
agent premain(), args: name=jar&age=33
hello world