一、javaagent
1.maven 依赖
<groupId>org.example</groupId>
<artifactId>agent-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.21.0-GA</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<id>shade-when-package</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.javassist:javassist</include>
</includes>
</artifactSet>
<shadeSourcesContent>true</shadeSourcesContent>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Agent-Class>com.example.agent.PremainAgent</Agent-Class>
<Premain-Class>com.example.agent.PremainAgent</Premain-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
2.agent 类
public class PremainAgent {
public static void premain(String agentOps, Instrumentation inst) {
inst.addTransformer(new DefineTransformer());
}
private static class DefineTransformer implements ClassFileTransformer {
public final String INJECTED_CLASS_NAME = "com.example.Person";
public final String METHOD_NAME = "sayHello";
@Override
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
className = className.replace("/", ".");
if (INJECTED_CLASS_NAME.equals(className)) {
try {
CtClass ctclass = ClassPool.getDefault().get(className);
CtMethod ctmethod = ctclass.getDeclaredMethod(METHOD_NAME);
// ctmethod.insertBefore("System.out.println(11111111);");
// 构建新的方法体
StringBuilder bodyStr = new StringBuilder();
bodyStr.append("{");
bodyStr.append("return 200;");
bodyStr.append("}");
ctmethod.setBody(bodyStr.toString());
return ctclass.toBytecode();
} catch (Throwable e) {
e.printStackTrace();
}
}
return classfileBuffer;
}
}
}
3.打包成 jar
mvn package
打包成 jar 包,agent-demo-1.0-SNAPSHOT.jar
二、使用
1.maven 依赖
<groupId>org.example</groupId>
<artifactId>java-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<!--<version>2.4</version>-->
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
2.Main 类
public class Person {
public int sayHello() {
// System.out.println("hello");
return 1;
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
int result = person.sayHello();
System.out.println(result);
}
}
3.打包
mvn package
4.测试
zxm@zxm-pc:~/IdeaProjects/java-demo$ java -javaagent:agent-demo-1.0-SNAPSHOT.jar -jar target/java-demo-1.0-SNAPSHOT.jar
200