在Java编程语言中,Java Agent是一种特殊的Java程序,它可以在Java应用程序运行时修改或监视字节码。Java Agent通常通过Java虚拟机 (JVM) 的Instrumentation API来实现这一点。
Jdk1.5 以后引入了 javaAgent
技术,javaAgent 是运行在方法之前的拦截器,相当于是对字节码进行的一个 AOP 操作,利用 javaAgent 和 ASM 字节码技术,在 JVM 加载 class 二进制文件的时候,利用 ASM 动态的修改加载的 class 文件。Javaagent 是 java 命令的一个参数。参数 javaagent 可以用于指定一个 jar 包。
对该 Java 包有 2 个要求:
Premain-Class
项premain()
方法-javaagent
所指定 jar 包内 Premain-Class
这个类的 premain
方法MANIFEST.MF
文件,必须包含 Premain-Class 选项,通常也会加入 Can-Redefine-Classes
和 Can-Retransform-Classes
选项premain
的类和 MANIFEST.MF
文件打成 jar
包,使用插件自动生成使用参数 -javaagent: jar包路径, 启动要代理的方法。
创建一个 Maven 工程:
添加依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>top.it6666</groupId>
<artifactId>JavaAgent</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<!--
自动添加 META-INF/MANIFEST.MF
-->
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Premain-Class>top.it6666.PreMainAgent</Premain-Class>
<Agent-Class>top.it6666.PreMainAgent</Agent-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
创建包, 在包中创建 PreMainAgent.java
:
/**
* @author yby6
**/
public class PreMainAgent {
/**
* 1、agentArgs 是 premain 函数得到的程序参数,随同 “– javaagent”一起传入。
* 与 main函数不同的是,
* 这个参数是一个字符串而不是一个字符串数组
* 2、Inst 是一个 java.lang.instrument.Instrumentation 的实例,
* 由 JVM 自动传入
* java.lang.instrument.Instrumentation 是 instrument 包中定义的一个接口,
* 也是这个包的核心部分,集中了其中几乎所有的功能方法,例如类定义的转换和操作等等。
**/
public static void premain (String agentArgs, Instrumentation inst) {
System.out.println ("========= premain方法执行1 ========");
System.out.println (agentArgs);
}
/**
* 如果不存在 premain(String agentArgs, Instrumentation inst)
* 则会执行 premain(String agentArgs)
*/
public static void premain (String agentArgs) {
System.out.println ("========= premain方法执行2 ========");
System.out.println (agentArgs);
}
}
使用 maven 的 package 命令进行打包:
创建 TestMain.java
测试类:记得编译一下搞到字节码
/**
* @author yby6
**/
public class TestMain {
public static void main (String[] args) {
System.out.println ("hello world");
}
}
在启动的时候, 配置 JavaAgent 参数,拷贝刚刚打包好的 jar 包的绝对路径:
配置参数:
配置的 JVM 的参数,新版本的 IDEA 需要开启这个配置如下图:
-javaagent:D:\Develop\IDEAPro\JavaAgent\target\JavaAgent-1.0-SNAPSHOT.jar=test
运行 TestMain.java 最终效果如下图所示:
本期结束咱们下次再见👋~
🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。