javaagent是java5的新特性,依赖他我们可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义,过程上简单来说就是编写一个特殊的类将其打成jar包,要监控(拦截)的项目在启动时jvm参数加上特殊的启动命令,即可监控该项目
javaagent使用步骤
任意编写一个类,类中有如下两个方法之一即可
123456/*** @param arg agentArgs 是 premain 函数得到的程序参数,随同 “– javaagent”一起传入。* @param instrumentation instrumentation 是一个 java.lang.instrument.Instrumentation 的实例,由 JVM 自动传入*/public static void premain(String arg, Instrumentation instrumentation){}public static void premain(String arg){}示例代码:
12345678package com.agenttest;import java.lang.instrument.Instrumentation;public class FirstAgent {//静态装载agentpublic static void premain(String arg, Instrumentation instrumentation){System.out.println("这里执行了premain()方法,进行了装载");}}在pom文件中加入如下配置,让该类在打包成jar包时他的MANIFEST.MF文件中有代表该类为Agent类的信息
12345678910111213141516171819202122<build><plugins><plugin><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><Premain-Class>com.agenttest.FirstAgent</Premain-Class><!-- <Boot-Class-Path>javassist-3.18.1-GA.jar</Boot-Class-Path><Agent-Class>com.agenttest.DynamicAgent</Agent-Class><Can-Redefine-Classes>true</Can-Redefine-Classes>--></manifestEntries></archive><skip>true</skip></configuration></plugin></plugins></build>在
标签下加上Agent类的全路径,完成后将该类所在的项目打成jar包
参数含义:12345678#动态agent 类Agent-Class: com.agenttest.DynamicAgent#agent 依懒包逗号分割Boot-Class-Path: javassist-3.18.1-GA.jar#是否允许重复装载Can-Redefine-Classes: true#静agent 类Premain-Class: com.agenttest.FirstAgent在运行要被”拦截”的项目时,添加一个jvm的启动参数
-javaagent:xxx.jar(=parama=aaa)
:xxx是jar包的路径,后面可以接着跟参数
测试类中示例代码:12345public class FirstAgentTest {public static void main(String[] args) {System.out.println("main方法中的输出");}}运行结果
会先执行premain中的方法,在执行main方法12这里执行了premain()方法,进行了装载main方法中的输出
javaagent的jar和普通jar区别
javaagent 底层流程
javaagent 装载时序图(premain):
Class 装载时序图