在字节好友中设置一个instanceField
Set an instanceField in Byte Buddy
我正在尝试了解如何使用 Byte Buddy 设置实例字段的值。文档说:
Always remember to assign a value to this field before calling methods on an instance of such a dynamic class. Otherwise, a method delegation will result in a NullPointerException.
但我在文档或单元测试中没有看到任何关于如何执行此操作的信息。
我的动态class是:
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();
我看到另一个 post 的答案是拦截任何构造函数并将 @FieldProxy
与 MethodDelegation
一起使用,但我不知道该怎么做。我在 .constructor(ElementMatchers.any()).intercept(...)
的某些变体中尝试的所有结果都会导致:
java.lang.IllegalArgumentException: None of [] allows for delegation from...
基本上,当您使用 MethodDelegation.toInstanceField
时,字节好友会在生成的 class 中添加一个给定名称的字段。在您的情况下,Byte Buddy 添加了一个类型为 service
的字段,名为 "consumer"
.
您现在需要决定如何为该字段分配值,因为该字段没有值,即在分配之前 null
。如果你在这样做之前调用了一个用 @Start
注释的方法,你会遇到 NullPointerException
.
分配字段的最简单方法是反射。一种类型安全的替代方法是实现一些接口
interface SetterIFace {
void setConsumer(MyType myType);
}
鉴于您的 service
类型是 Class<MyType>
。然后您可以添加:
.implement(SetterIFace.class).intercept(FieldAccessor.ofBeanProperty())
在 MethodDelegation
.
中定义相关字段后,SetterIFace
作为相关字段的 setter 实施
我正在尝试了解如何使用 Byte Buddy 设置实例字段的值。文档说:
Always remember to assign a value to this field before calling methods on an instance of such a dynamic class. Otherwise, a method delegation will result in a NullPointerException.
但我在文档或单元测试中没有看到任何关于如何执行此操作的信息。
我的动态class是:
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();
我看到另一个 post 的答案是拦截任何构造函数并将 @FieldProxy
与 MethodDelegation
一起使用,但我不知道该怎么做。我在 .constructor(ElementMatchers.any()).intercept(...)
的某些变体中尝试的所有结果都会导致:
java.lang.IllegalArgumentException: None of [] allows for delegation from...
基本上,当您使用 MethodDelegation.toInstanceField
时,字节好友会在生成的 class 中添加一个给定名称的字段。在您的情况下,Byte Buddy 添加了一个类型为 service
的字段,名为 "consumer"
.
您现在需要决定如何为该字段分配值,因为该字段没有值,即在分配之前 null
。如果你在这样做之前调用了一个用 @Start
注释的方法,你会遇到 NullPointerException
.
分配字段的最简单方法是反射。一种类型安全的替代方法是实现一些接口
interface SetterIFace {
void setConsumer(MyType myType);
}
鉴于您的 service
类型是 Class<MyType>
。然后您可以添加:
.implement(SetterIFace.class).intercept(FieldAccessor.ofBeanProperty())
在 MethodDelegation
.
SetterIFace
作为相关字段的 setter 实施