JavaAgent 是运行在 main方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain 方法然后再执行 main 方法。
Javaagent 只要作用在class被类加载器加载之前对其加载,并且可以修改类的字节码,插入我们需要添加的字节码。从而可以达到监控类的目的。
入门demo:
1.新建一个maven项目:

首先看带premain函数的类:
package club.jiajiajia.demo.agent;
import java.lang.instrument.Instrumentation;
public class MyAgent {
/**
* 该方法在main方法之前运行,与main方法运行在同一个JVM中
* 并被同一个System ClassLoader装载
* 被统一的安全策略(security policy)和上下文(context)管理
*/
public static void premain(String agentOps, Instrumentation inst) {
System.out.println("=========premain========");
inst.addTransformer(new FirstAgent());
}
}
在FirstAgent类中修改类的字节码:
package club.jiajiajia.demo.agent;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class FirstAgent implements ClassFileTransformer {
public final String injectedClassName = "agentTest.User";
public final String methodName = "myName";
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
className = className.replace("/", ".");
if (className.equals(injectedClassName)) {
CtClass ctclass = null;
try {
ctclass = ClassPool.getDefault().get(className);// 使用全称,用于取得字节码类<使用javassist>
CtMethod ctmethod = ctclass.getDeclaredMethod(methodName);// 得到这方法实例
ctmethod.insertBefore("System.out.println(\"I'm here to make trouble.\");");
return ctclass.toBytecode();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
return null;
}
}
pom文件:
<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>test</groupId>
<artifactId>test3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.23.1-GA</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Premain-Class>club.jiajiajia.demo.agent.MyAgent</Premain-Class>
<!--上面一定要填写MyAgent的全类名,也可以在MANIFEST.MF文件中配置-->
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此时我们执行:clean package 命令打包,然后得到我们需要的jar包,这个包会在后面用到->

2.新建一个测试项目:(当然也可以在上一个项目中测试)

User类:
package agentTest;
public class User {
public User(String name) {
super();
this.name = name;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public String name;
public void myName(){
System.out.println(name);
}
}
主测试类:
package agentTest;
public class mainTest {
public static void main(String[] args) {
User u=new User("佳佳");
u.myName();
}
}
下面是重点:
在启动参数中配置javaagent:
右键项目->Run as->Run configurations


运行结果:

