Java Agent 个人简单理解为 可以在启动时给一个正常的java程序注入代码
案例demo
首先新建一个maven项目
自己的目录结构如下
JavaAgentTest.java
package com.ceshi;
import java.lang.instrument.Instrumentation;
public class JavaAgentTest {
public static void premain(String agentArgs, Instrumentation inst) {
System.err.println("==============启动之前执行===================");
System.err.println("agentArgs : " + agentArgs);
// 添加Transformer
inst.addTransformer(new TransformerTest());
}
}
TransformerTest.java
package com.ceshi;
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 TransformerTest implements ClassFileTransformer {
public final String TEST_CLASS_NAME = "com.bilibili.test.javaweb.HellofoolController";
public final String METHOD_NAME = "test";
@Override
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
String finalClassName = className.replace("/", ".");
if (TEST_CLASS_NAME.equals(finalClassName)) {
System.err.println("启动中执行");
CtClass ctClass;
try {
ctClass = ClassPool.getDefault().get(finalClassName);
System.err.println("启动中执行1");
CtMethod ctMethod = ctClass.getDeclaredMethod(METHOD_NAME);
System.err.println("启动中执行2");
ctMethod.insertBefore("System.err.println(\"通过javaAgebt插入了代码\");");
ctMethod.insertBefore("text = \"text被javaAgebt篡改了\";");
return ctClass.toBytecode();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
return null;
}
}
然后在pom.xml文件里加上这些
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.29.2-GA</version>
</dependency>
</dependencies>
<build>
<finalName>test-agent</finalName>
<plugins>
<!--
META-INF 下需要一个 MANIFEST.MF 文件
下面Maven插件可以自动实现
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</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>com.ceshi.JavaAgentTest</Premain-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
然后用maven打成jar包就行
.
.
.
在一个Springboot项目上测试
建一个简单springboot项目
自己项目结构如下
JDK1.8 + Springboot 2.7.12-SNAPSHOT
HellofoolController.jar
package com.bilibili.test.javaweb;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HellofoolController {
String text = "我是正确的数据";
@GetMapping("/test")
public String test(){
System.out.println("这里会被插入代码");
return text;
}
@GetMapping("/test1")
public String test1(){
return text;
}
}
然后在这个springboot项目的启动参数里添加这个
-javaagent: 填JavaAgent项目的maven打包的地址
填完记得点 应用
如果你没有上面这个选项的话, 将下图中所示的选项勾选
然后运行Springboot 项目就能看到注入的代码
*
*
*
*
下面是对应关系
*
*
*
效果:
没有被注入的方法正常显示
*
注入了的方法显示:
*
*
*
项目压缩包下载
https://cowtransfer.com/s/bfb43f833f9d48