gpt4 book ai didi

java - 如何使用 bytebuddy 在现有类中定义新方法并在同一类中的现有方法中添加对它的调用?

转载 作者:行者123 更新时间:2023-12-01 18:55:25 35 4
gpt4 key购买 nike

我有一个如下所示的类(class)

public class HelloWorld{
public void sayHelloWorld(){
System.out.println("Hello World");
}
}

现在我想使用 bytebuddy 向 HelloWorld 类添加另一个方法,并在 sayHelloWorld 中添加对新方法的调用。因此,假设在 bytebuddy 施展魔法之后,类将会是这样的。 (我知道 bytebuddy 使用字节码而不是 java 源文件。下面的代码仅用于说明目的。)

public class HelloWorld{
public void sayHelloWorld(){
System.out.println("Hello World");
sayHelloAgain()
}
public void sayHelloAgain(){
System.out.println("Hello Again")
}
}
  1. 首先,这对于bytebuddy来说可能吗?
  2. 第二,如果可以的话,我该怎么做?我了解到bytebuddy可以用来重新定义方法,但不能修改方法体。这是真的吗?

如果有人能阐明这一点,那就太好了。 TIA!

最佳答案

Byte Buddy 允许您以多种方式执行此操作。最直接的方法是定义一个实现 sayHelloAgain 的拦截器,Byte Buddy 会向该拦截器创建委托(delegate):

public class HelloAgainDelegate {
public static void sayHelloAgain() {
System.out.println("Hello again");
}
}

然后,您可以在重新定义的类上定义该方法,并重新设置 sayHelloWorld 方法的基础,以首先调用原始方法,然后调用另一个方法:

Class<?> type = new ByteBuddy()
.rebase(HelloWorld.class)
.defineMethod("sayHelloAgain", void.class, Visibility.PUBLIC)
.intercept(MethodDelegation.to(HelloAgainDelegate.class))
.method(named("sayHelloWorld"))
.intercept(SuperMethodCall.INSTANCE
.andThen(MethodCall.invoke(named("sayHelloAgain"))))
.make()
.load(HelloWorld.class.getClassLoader(),
ClassLoadingStrategy.Default.CHILD_FIRST)
.getLoaded();

Object instance = type.newInstance();
type.getMethod("sayHelloWorld").invoke(instance);
type.getMethod("sayHelloAgain").invoke(instance);

在 Java 代码中,重新基化的类看起来像这样:

public class HelloWorld {
synthetic void sayHelloWorld$origin() {
System.out.println("Hello World");
}

public void sayHelloWorld() {
sayHelloWorld$origin();
sayHelloAgain();
}

public void sayHelloAgain() {
HelloAgainInterceptor.sayHelloAgain();
}
}

如果此委托(delegate)不适合您,您还可以使用 Advice 从模板类内联代码:

class HelloAgainAdvice {
@Advice.OnMethodExit
static void sayHelloAgain() {
System.out.println("Hello again");
}
}

您可以通过 Advice.to(HelloAgainAdvice.class) 使用此类,而不是使用 MethodDelegation。复制代码时,您将无法设置断点,但重新定义的类将是独立的。

关于java - 如何使用 bytebuddy 在现有类中定义新方法并在同一类中的现有方法中添加对它的调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46384919/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com