Java 如何在ByteBuddy中将字段添加到类中,并在方法拦截器中设置/获取该值

Java 如何在ByteBuddy中将字段添加到类中,并在方法拦截器中设置/获取该值,java,bytecode,byte-buddy,Java,Bytecode,Byte Buddy,我正在使用byte buddy在Ignite之上构建一个ORM,我们需要在类中添加一个字段,然后在方法拦截器中访问它 下面是一个例子,我在类中添加了一个字段 final ByteBuddy buddy = new ByteBuddy(); final Class<? extends TestDataEnh> clz = buddy.subclass(TestDataEnh.class) .defineField("stringVal",String.class)

我正在使用byte buddy在Ignite之上构建一个ORM,我们需要在类中添加一个字段,然后在方法拦截器中访问它

下面是一个例子,我在类中添加了一个字段

final ByteBuddy buddy = new ByteBuddy();

final Class<? extends TestDataEnh> clz =  buddy.subclass(TestDataEnh.class)
        .defineField("stringVal",String.class)
        .method(named("setFieldVal")).intercept(
            MethodDelegation.to(new SetterInterceptor())
    )
    .make()
    .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
    .getLoaded();

final TestDataEnh enh = clz.newInstance();

enh.getFieldVal();
enh.setFieldVal();

System.out.println(enh.getClass().getName());
那么,如何将新字段的值放入拦截器中,以便更改它的值呢?(斯特林瓦尔)

提前感谢

您可以使用按名称访问字段。您需要安装一个
FieldProxy.Binder
,并在
methodedelegation
上注册它,然后才能使用它,因为它需要一个自定义类型来进行类型安全检测。javadoc解释了如何做到这一点。或者,您可以通过使用
@This
对实例使用反射。JVM在优化反射的使用方面非常有效

例如:

interface FieldGetter {
  Object getValue();
}

interface FieldSetter {
  void setValue(Object value);
}

public class SetterInterceptor {
  @RuntimeType
  public  Object intercept(@FieldProxy("stringVal") FieldGetter accessor) {
    Object value = accessor.getValue();
    System.out.println("Invoked method with: " + value);
    return value;
  }
}
对于bean属性,
FieldProxy
注释不需要显式名称,而是从截获的getter或setter的名称中发现名称

安装过程如下所示:

MethodDelegation.to(SetterInterceptor.class)
                .appendParameterBinder(FieldProxy.Binder.install(FieldGetter.class, 
                                                                 FieldSetter.class));

好的,在我的例子中,直到运行时我们才知道字段的名称,但我认为您已经给了我足够的时间来处理。。我们正在添加一个隐藏字段来存储类中的一些关系信息,然后再将其序列化到数据存储区..仅供将来参考此堆栈溢出。。如果直到运行时才知道字段的名称,如何访问该字段?我正在查看FieldProxy.Binder.install(TypeDescription.AbstractBase.OfSimpleType)将字段名放入,但我在其中迷失了方向。字段名是否遵循Java bean约定?只需将字段保留为空。否则,您实际上可以在
@此
对象上使用反射。只要缓存
字段
实例,这与性能无关。a反射的成功是通过使用
sun.misc.Unsafe
直接从堆中读取来实现的。没有字节码生成可以与此级别的性能竞争。
MethodDelegation.to(SetterInterceptor.class)
                .appendParameterBinder(FieldProxy.Binder.install(FieldGetter.class, 
                                                                 FieldSetter.class));