隨着ByteBuddy我試圖找到一種有效的方式來生成一個代理,僅僅轉發所有方法調用同一類型的基礎委託實例,我來到這個防空火炮:How to implement a wrapper decorator in Java?,我試圖執行建議的解決方案,但沒有任何成功,表面上我粗略猜測,對ByteBuddy的內部知道不多的時候,它看起來像檢查匹配委託的方法簽名時,可能會考慮下面的intercept
方法的@FieldValue註釋參數嗎?我的使用情況更加複雜了一點,但我寫了一個簡單的單元測試重現同樣的問題,我使用ByteBuddy版本1.5.13:如何使用ByteBuddy @Pipe註解與@FieldValue實現委託模式?
@Test
public void testDelegate() throws Exception {
Object delegate = "aaa";
Class<?> delegateClass = new ByteBuddy().subclass(Object.class)
.method(ElementMatchers.any()).intercept(MethodDelegation.to(Interceptor.class).defineParameterBinder(Pipe.Binder.install(Function.class)))
.defineField("delegate", Object.class, Modifier.PUBLIC)
.make()
.load(getClass().getClassLoader())
.getLoaded();
Object obj = delegateClass.newInstance();
delegateClass.getField("delegate").set(obj, delegate);
assertThat(obj, equalTo("aaa"));
}
這個攔截器工作正常和單元測試順利過關:
public static class Interceptor {
@RuntimeType
public static Object intercept(@Pipe Function<Object, Object> pipe) {
return pipe.apply("aaa");
}
}
但是,如果我這一個替換上面的攔截,並嘗試以@FieldValue注入委託場:
public static class Interceptor {
@RuntimeType
public static Object intercept(@Pipe Function<Object, Object> pipe, @FieldValue("delegate") Object delegate) {
return pipe.apply(delegate);
}
}
我得到以下錯誤:
java.lang.IllegalArgumentException: None of [public static java.lang.Object io.github.pellse.decorator.DecoratorTest$Interceptor.intercept(java.util.function.Function,java.lang.Object)] allows for delegation from public boolean java.lang.Object.equals(java.lang.Object)
at net.bytebuddy.implementation.bind.MethodDelegationBinder$Processor.process(MethodDelegationBinder.java:881)
at net.bytebuddy.implementation.MethodDelegation$Appender.apply(MethodDelegation.java:1278)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:678)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:667)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:586)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:4305)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1796)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:172)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:153)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2568)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2670)
at io.github.pellse.decorator.DecoratorTest.testDelegate(DecoratorTest.java:476)
所以我想知道如果我正確地使用@管/ @ fieldValue方法註釋或是否有另一種方式的委託方法與ByteBuddy生成代理調用時?提前致謝!
我的使用情況下,我的項目加上「攔截(MethodCall.invokeSelf()。onField(代表).withAllArguments())」,非常感謝指導的偉大工程! –
當我嘗試'invokeSelf()onField()'上面的單元測試,我得到: 'java.lang.VerifyError的:在invokevirtual 異常詳細信息受保護的數據錯誤訪問: 位置: 網/ bytebuddy /改名/java/lang/Object$ByteBuddy$POYl6ppy.clone()Ljava/lang/Object; @ 4:invokevirtual 原因: 類型 '的java /郎/對象'(當前幀,堆棧[0])是不能分配給淨/ bytebuddy /重命名/爪哇/郎/對象$ $ ByteBuddy POYl6ppy'' \t 當我調用delegateClass時。newInstance(),如果我過濾出'clone()'方法,一切正常,委託給一個受保護的方法不會有多大意義 –
我更新了Byte Buddy以引發一個意外的異常。看到我更新的答案。 –