[英]How to define a new method inside an existing class and add a call to it in an existing method inside the same class using bytebuddy?
I have a class which looks like below我有一个看起来像下面的类
public class HelloWorld{
public void sayHelloWorld(){
System.out.println("Hello World");
}
}
Now I would like to add another method to the HelloWorld class using bytebuddy and add a call to the new method in sayHelloWorld .现在我想使用 bytebuddy 向HelloWorld类添加另一个方法,并在sayHelloWorld 中添加对新方法的调用。 So hypothetically the class would look like this after bytebuddy does it's magic.
因此,假设在 bytebuddy 发挥魔力之后,该类将看起来像这样。 (I know that bytebuddy works with bytecode and not java source files. The below code is just for illustration purpose.)
(我知道 bytebuddy 使用字节码而不是 java 源文件。以下代码仅用于说明目的。)
public class HelloWorld{
public void sayHelloWorld(){
System.out.println("Hello World");
sayHelloAgain()
}
public void sayHelloAgain(){
System.out.println("Hello Again")
}
}
It would be great if someone could shed some light on this.如果有人能对此有所了解,那就太好了。 TIA!
蒂亚!
Byte Buddy allows you to do this in various ways. Byte Buddy 允许您以各种方式执行此操作。 The most straight forward way would be to define an interceptor that implements
sayHelloAgain
to which Byte Buddy creates a delegation:最直接的方法是定义一个实现
sayHelloAgain
的拦截器,Byte Buddy 创建一个委托:
public class HelloAgainDelegate {
public static void sayHelloAgain() {
System.out.println("Hello again");
}
}
You can then define the method on the redefined class and rebase the sayHelloWorld
method to first invoke the original method and then invoke the other method:然后,您可以在重新定义的类上定义该方法,并重新定义
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);
In Java code, the rebased class would look something like this:在 Java 代码中,重新定位的类看起来像这样:
public class HelloWorld {
synthetic void sayHelloWorld$origin() {
System.out.println("Hello World");
}
public void sayHelloWorld() {
sayHelloWorld$origin();
sayHelloAgain();
}
public void sayHelloAgain() {
HelloAgainInterceptor.sayHelloAgain();
}
}
If this delegation is not an option for you, you can also use Advice
to inline the code from a template class:如果此委托不适合您,您还可以使用
Advice
来内联模板类中的代码:
class HelloAgainAdvice {
@Advice.OnMethodExit
static void sayHelloAgain() {
System.out.println("Hello again");
}
}
Instead of the MethodDelegation
, you would use this class via Advice.to(HelloAgainAdvice.class)
.您可以通过
Advice.to(HelloAgainAdvice.class)
使用此类,而不是MethodDelegation
。 As the code is copied, you will not be able to set break points but your redefined class will be self-contained.复制代码后,您将无法设置断点,但您重新定义的类将是独立的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.