ByteBuddy:如何进行方法委托/转发到可变字段
ByteBuddy: How to do method delegation / forwarding to a volatile field
我有这样的(伪代码):
final Class<OUT> newClass = (Class<OUT>) new ByteBuddy()
.subclass(Object.class)
.name(newName)
.implement(SomeInterface.class, SomeOtherInterface.class)
.method(ElementMatchers.isMethod())
.intercept(
ExceptionMethod.throwing(UnsupportedOperationException.class,
"calling this method is not supported"))
// in fact I am matching for more than a single method here
.method(ElementMatchers.named("getUuid"))
.intercept(
MethodDelegation.toInstanceField(SomeOtherInterface.class, "delegate"))
.make()
.load(aBusinessEntityClass.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
我当前的问题是:我需要我的 delegate 字段是 volatile。我怎样才能做到这一点?
好的,找到适合我的解决方案,以防有人感兴趣:
final Class<OUT> newClass = (Class<OUT>) new ByteBuddy()
.subclass(Object.class)
.name(newName)
.implement(SomeInterface.class, SomeOtherInterface.class)
.method(ElementMatchers.isMethod())
.intercept(
ExceptionMethod.throwing(UnsupportedOperationException.class,
"calling this method is not supported"))
// in fact I am matching for more than a single method here
.method(ElementMatchers.named("getUuid"))
.intercept(
MethodDelegation.toInstanceField(SomeOtherInterface.class, "delegate"))
// -- HERE THE FIELD IS MODIFIED AGAIN, IN THIS CASE AS --
// -- PRIVATE & VOLATILE --
.field(ElementMatchers.named("delegate"))
.transform(Transformer.ForField.withModifiers(FieldManifestation.VOLATILE, Visibility.PRIVATE))
.make()
.load(aBusinessEntityClass.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
解决方案是随后通过调用 field() 和 transform() 并适当 Transformer.ForField.withModifiers().
希望对遇到这个问题的大家有所帮助。
toInstanceField
API 已随 Byte Buddy 1.5.0 一起退役,取而代之的是新工具 API,您更愿意在其中明确定义字段:
new ByteBuddy()
.defineField("delegate", SomeOtherInterface.class, VOLATILE)
.method(ElementMatchers.named("getUuid"))
.intercept(MethodDelegation.toField("delegate"));
这允许做其他事情,例如添加注释等
此方法现已应用于所有 Implementation
。今天发布了新版本
我有这样的(伪代码):
final Class<OUT> newClass = (Class<OUT>) new ByteBuddy()
.subclass(Object.class)
.name(newName)
.implement(SomeInterface.class, SomeOtherInterface.class)
.method(ElementMatchers.isMethod())
.intercept(
ExceptionMethod.throwing(UnsupportedOperationException.class,
"calling this method is not supported"))
// in fact I am matching for more than a single method here
.method(ElementMatchers.named("getUuid"))
.intercept(
MethodDelegation.toInstanceField(SomeOtherInterface.class, "delegate"))
.make()
.load(aBusinessEntityClass.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
我当前的问题是:我需要我的 delegate 字段是 volatile。我怎样才能做到这一点?
好的,找到适合我的解决方案,以防有人感兴趣:
final Class<OUT> newClass = (Class<OUT>) new ByteBuddy()
.subclass(Object.class)
.name(newName)
.implement(SomeInterface.class, SomeOtherInterface.class)
.method(ElementMatchers.isMethod())
.intercept(
ExceptionMethod.throwing(UnsupportedOperationException.class,
"calling this method is not supported"))
// in fact I am matching for more than a single method here
.method(ElementMatchers.named("getUuid"))
.intercept(
MethodDelegation.toInstanceField(SomeOtherInterface.class, "delegate"))
// -- HERE THE FIELD IS MODIFIED AGAIN, IN THIS CASE AS --
// -- PRIVATE & VOLATILE --
.field(ElementMatchers.named("delegate"))
.transform(Transformer.ForField.withModifiers(FieldManifestation.VOLATILE, Visibility.PRIVATE))
.make()
.load(aBusinessEntityClass.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
解决方案是随后通过调用 field() 和 transform() 并适当 Transformer.ForField.withModifiers().
希望对遇到这个问题的大家有所帮助。
toInstanceField
API 已随 Byte Buddy 1.5.0 一起退役,取而代之的是新工具 API,您更愿意在其中明确定义字段:
new ByteBuddy()
.defineField("delegate", SomeOtherInterface.class, VOLATILE)
.method(ElementMatchers.named("getUuid"))
.intercept(MethodDelegation.toField("delegate"));
这允许做其他事情,例如添加注释等
此方法现已应用于所有 Implementation
。今天发布了新版本