我正在试图弄清楚如何使用Byte Buddy设置实例字段的值。文档说:
在调用此类动态类的实例上的方法之前,请务必记住为此字段指定值。否则,方法委派将导致NullPointerException。
但我没有在文档或单元测试中看到如何执行此操作。
我的动态课程是:
new ByteBuddy().subclass(AbstractService.class)
.name(serviceName)
.method(ElementMatchers.named("start").and(
ElementMatchers.takesArguments(0)))
.intercept(
MethodDelegation.toInstanceField(service, "consumer")
.filter(ElementMatchers.isAnnotatedWith(Start.class)))
.method(ElementMatchers.named("stop").and(
ElementMatchers.takesArguments(0)))
.intercept(
MethodDelegation.to(instance).filter(
ElementMatchers.isAnnotatedWith(Stop.class)))
.make();
我看到另一篇帖子的答案是拦截任何构造函数,并使用@FieldProxy
和MethodDelegation
,但我不明白该怎么做。我在.constructor(ElementMatchers.any()).intercept(...)
的某些变体的结果方面尝试过的所有内容都会导致:
java.lang.IllegalArgumentException:[]不允许来自...的委派
答案 0 :(得分:0)
基本上,当您使用MethodDelegation.toInstanceField
时,Byte Buddy会在生成的类中添加给定名称的字段。在您的情况下,Byte Buddy添加了一个名为service
的{{1}}字段。
现在,您需要决定如何为此字段指定值,因为该字段没有值,即在分配之前为"consumer"
。如果在执行此操作之前调用了使用null
注释的方法,则会遇到@Start
。
分配字段的最简单方法是反射。类型安全的替代方案是实现一些接口
NullPointerException
鉴于您的interface SetterIFace {
void setConsumer(MyType myType);
}
类型为service
。然后,您可以添加:
Class<MyType>
在.implement(SetterIFace.class).intercept(FieldAccessor.ofBeanProperty())
中定义后,将SetterIFace
实施为相关字段的设置者。