随着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以引发一个意外的异常。看到我更新的答案。 –