当然可以!下面是一个使用 Byte Buddy 实现 Java Agent 的完整示例,演示如何在不修改原始类代码的情况下,动态地拦截并增强一个方法的行为。
我们将实现一个简单的 Java Agent,它会在目标方法执行前后打印日志 —— 类似 AOP 的功能。
使用 Byte Buddy 编写 Java Agent:方法拦截与增强实战
项目结构(Maven)
byte-buddy-agent/
├── src/
│ └── main/
│ ├── java/
│ │ ├── MyAgent.java <-- Java Agent 入口
│ │ └── HelloTransformer.java <-- ClassFileTransformer
│ └── resources/
│ └── MANIFEST.MF
└── pom.xml
添加 Maven 依赖(pom.xml
)
<dependencies>
<!-- Byte Buddy 核心库 -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.0</version>
</dependency>
<!-- 可选:用于运行测试的目标类 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
编写 Java Agent 主类(MyAgent.java
)
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;
public class MyAgent {
public static void premain(String args, Instrumentation inst) {
System.out.println("Java Agent 加载成功...");
new AgentBuilder.Default()
.type(ElementMatchers.named("com.example.MyService")) // 拦截指定类
.transform((builder, typeDescription, classLoader, module) ->
builder.method(ElementMatchers.named("sayHello")) // 拦截 sayHello 方法
.intercept(Advice.to(HelloMethodAdvice.class)) // 插入增强逻辑
).installOn(inst);
}
}
定义增强逻辑(HelloMethodAdvice.java
)
import net.bytebuddy.asm.Advice;
public class HelloMethodAdvice {
@Advice.OnMethodEnter
public static void beforeMethod() {
System.out.println("[Before] 正在调用 sayHello 方法...");
}
@Advice.OnMethodExit
public static void afterMethod() {
System.out.println("[After] sayHello 方法执行完成。");
}
}
配置 MANIFEST.MF 文件
在 resources/MANIFEST.MF
中写入:
Manifest-Version: 1.0
Premain-Class: MyAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true
打包 Agent JAR
使用 Maven 打包:
mvn clean package
生成的 JAR 包位于:target/byte-buddy-agent-1.0-SNAPSHOT.jar
准备目标类(可选测试用)
创建一个测试类 com.example.MyService
:
package com.example;
public class MyService {
public String sayHello() {
return "Hello from MyService!";
}
public static void main(String[] args) {
MyService service = new MyService();
System.out.println(service.sayHello());
}
}
运行测试命令
启动时带上 Agent:
java -javaagent:target/byte-buddy-agent-1.0-SNAPSHOT.jar -cp target/classes com.example.MyService
输出结果:
Java Agent 加载成功...
[Before] 正在调用 sayHello 方法...
Hello from MyService!
[After] sayHello 方法执行完成。