在 Bytebuddy 中进行现场方法委托和投射
Method delegation on field and cast in Bytebuddy
使用 Bytebuddy 假设以下情况:
class Service {
protected Handler handler;
...
}
interface Handler {
public void handle();
}
class ConcreteHandler implements Handler {
public void handle() {
...
}
public void handle2() {
...
}
}
一般我们调用Handler的handle()方法,但有些情况下需要调用ConcreteHandler的class的handle2()方法,也就是运行时。现在的问题是:可以使用 Bytebuddy 吗?可能是,但如何?
我试过了:
if (condition) {
MethodCall methodCall = (MethodCall)
MethodCall.invoke(methodHandle2).onField("handler")
.withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC);
}
... 但它因 IllegalStateException 而失败:无法调用 public void com.framework.ConcreteHandler.handle2(...) on protected com.framework.Handler com.framework.Service.handler
有什么想法吗?
如果您的字段变量是 Handler
,您不能调用 handle2()
,因为处理程序不知道 handle2()
方法。
为了调用 handle2()
方法(对于有效的 class),您需要将 handler
转换为 ConcreteHandler
- 一个已知的过程当您将实例转换为对象层次结构中较低的对象时,就像“向下转换”一样。这仅在 handler
实例实际上是 ConcreteHandler
而不是 Handler
.
的其他派生时才有效
示例:
if (handler instanceof ConcreteHandler) {
ConcreteHandler concreteHandler = (ConcreteHandler) handler;
concreteHandler.handle2();
}
编辑:
我开始工作的一次性重定向。我不完全确定你如何让它作为文档的永久重定向工作,但如果你想永久重定向该方法,重新定义似乎会起作用。还对制作 classes ConcreteHandler、Handler 等 public.
所需的源代码进行了更改
new ByteBuddy()
.subclass(ConcreteHandler.class)
.method(named("handle")).intercept(MethodDelegation.to(ConcreteHandler.class))
.make()
.load(getClass().getClassLoader())
.getLoaded()
.newInstance()
.handle2();
这似乎是字节好友中的一个错误。我希望解决问题 in this commit,这应该可以解决 Byte Buddy 1.10.14 中的问题。您可以同时尝试快照。
使用 Bytebuddy 假设以下情况:
class Service {
protected Handler handler;
...
}
interface Handler {
public void handle();
}
class ConcreteHandler implements Handler {
public void handle() {
...
}
public void handle2() {
...
}
}
一般我们调用Handler的handle()方法,但有些情况下需要调用ConcreteHandler的class的handle2()方法,也就是运行时。现在的问题是:可以使用 Bytebuddy 吗?可能是,但如何?
我试过了:
if (condition) {
MethodCall methodCall = (MethodCall)
MethodCall.invoke(methodHandle2).onField("handler")
.withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC);
}
... 但它因 IllegalStateException 而失败:无法调用 public void com.framework.ConcreteHandler.handle2(...) on protected com.framework.Handler com.framework.Service.handler
有什么想法吗?
如果您的字段变量是 Handler
,您不能调用 handle2()
,因为处理程序不知道 handle2()
方法。
为了调用 handle2()
方法(对于有效的 class),您需要将 handler
转换为 ConcreteHandler
- 一个已知的过程当您将实例转换为对象层次结构中较低的对象时,就像“向下转换”一样。这仅在 handler
实例实际上是 ConcreteHandler
而不是 Handler
.
示例:
if (handler instanceof ConcreteHandler) {
ConcreteHandler concreteHandler = (ConcreteHandler) handler;
concreteHandler.handle2();
}
编辑: 我开始工作的一次性重定向。我不完全确定你如何让它作为文档的永久重定向工作,但如果你想永久重定向该方法,重新定义似乎会起作用。还对制作 classes ConcreteHandler、Handler 等 public.
所需的源代码进行了更改 new ByteBuddy()
.subclass(ConcreteHandler.class)
.method(named("handle")).intercept(MethodDelegation.to(ConcreteHandler.class))
.make()
.load(getClass().getClassLoader())
.getLoaded()
.newInstance()
.handle2();
这似乎是字节好友中的一个错误。我希望解决问题 in this commit,这应该可以解决 Byte Buddy 1.10.14 中的问题。您可以同时尝试快照。