Java 在Byte Buddy中设置instanceField

Java 在Byte Buddy中设置instanceField,java,bytecode,instrumentation,byte-buddy,Java,Bytecode,Instrumentation,Byte Buddy,我试图弄清楚如何使用Byte Buddy设置实例字段的值。文件说: 在对此类动态类的实例调用方法之前,请始终记住为此字段指定一个值。否则,方法委派将导致NullPointerException 但是我在文档或单元测试中没有看到关于如何做到这一点的内容 我的动态课程是: new ByteBuddy().subclass(AbstractService.class) .name(serviceName) .method(ElementMatchers.named("s

我试图弄清楚如何使用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:[]中的任何一个都不允许从


基本上,当您使用
MethodDelegation.toInstanceField
时,Byte Buddy会将给定名称的字段添加到生成的类中。在您的例子中,Byte Buddy添加了一个类型为
service
的字段,名为
“consumer”

现在,您需要决定如何为该字段赋值,因为该字段没有值,即赋值前为
null
。如果在执行此操作之前调用了带有
@Start
注释的方法,则会遇到
NullPointerException

指定字段的最简单方法是反射。类型安全的替代方案是实现一些接口

interface SetterIFace {
  void setConsumer(MyType myType);
}
假设您的
服务
类型是
。然后,您可以添加:

.implement(SetterIFace.class).intercept(FieldAccessor.ofBeanProperty())

MethodDelegation

中定义相关字段后,要将
setterface
实现为相关字段的setter,基本上,当您使用
MethodDelegation.toInstanceField
时,Byte Buddy会将给定名称的字段添加到生成的类中。在您的例子中,Byte Buddy添加了一个类型为
service
的字段,名为
“consumer”

现在,您需要决定如何为该字段赋值,因为该字段没有值,即赋值前为
null
。如果在执行此操作之前调用了带有
@Start
注释的方法,则会遇到
NullPointerException

指定字段的最简单方法是反射。类型安全的替代方案是实现一些接口

interface SetterIFace {
  void setConsumer(MyType myType);
}
假设您的
服务
类型是
。然后,您可以添加:

.implement(SetterIFace.class).intercept(FieldAccessor.ofBeanProperty())
MethodDelegation
中定义相关字段后,将
SetterIFace
实现为相关字段的setter