gpt4 book ai didi

java - 字节好友 : Use new defined field in intercept during construction of class

转载 作者:行者123 更新时间:2023-11-30 02:41:22 27 4
gpt4 key购买 nike

我正在查看其他人的一些 ByteBuddy 代码。他使用ByteBuddy生成运行时子类,这些子类用作代理,将运行时的一些管理代码实现到特定对象中。

Class<? extends T> newSubClass = new ByteBuddy(ClassFileVersion.ofThisVm())
.subclass(classType)
.defineField("_core", Object.class, Visibility.PUBLIC) //<---
.method(ElementMatchers.isDeclaredBy(classType))
.intercept(InvocationHandlerAdapter.of((proxy, method, m_args) -> {
//TODO: Need to replace core with _core as core is a function argument and will make it bound
return proxyHandler(core, method, m_args); //<--
}))
.make()
.load(roleType.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();


T proxy = ReflectionHelper.newInstance(newSubClass, args);
newSubClass.getField("_core").set(proxy, core);

为了不将 core 对象直接绑定(bind)到 lambda 中,我想使用新定义的字段 _core 这样我就可以重用生成的类(而不是重新生成它)对于该函数的每次调用)。 有没有办法实现这个目标?

提前致谢。

最佳答案

您可以像定义方法一样定义自定义构造函数。定义构造函数的一个要点是您需要另一个构造函数调用作为其第一条指令。您可以使用 MethodCall::invoke 调用构造函数,您可以将其与 FieldAccessor::ofField 结合使用。

这样,您就可以定义类似于以下内容的类:

new ByteBuddy(ClassFileVersion.ofThisVm())
.subclass(classType, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.defineConstructor(Visibility.PUBLIC)
.withParameter(InvocationHandler.class)
.intercept(MethodCall.invoke(classType.getDeclaredConstructor())
.andThen(FieldAccessor.ofField("_core").setsArgumentAt(0)))
.defineField("_core", InvocationHandler.class, Visibility.PUBLIC)
.method(ElementMatchers.isDeclaredBy(classType))
.intercept(InvocationHandlerAdapter.toField("_core"))
.make();

这样,您就可以为每个实例设置一个自定义的InitationHandler。如果您只想将状态存储在 _core 字段中并从拦截器访问该字段,请查看 MethodDelegation:

new ByteBuddy(ClassFileVersion.ofThisVm())
.subclass(classType, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.defineConstructor(Visibility.PUBLIC)
.withParameter(Object.class)
.intercept(MethodCall.invoke(classType.getDeclaredConstructor())
.andThen(FieldAccessor.ofField("_core").setsArgumentAt(0)))
.defineField("_core", Object.class, Visibility.PUBLIC)
.method(ElementMatchers.isDeclaredBy(classType))
.intercept(MethodDelegation.to(MyHandler.class))
.make();

public class MyHandler {
@RuntimeType
public static Object intercept(@FieldValue("_core") Object value) { ... }
}

您可能需要的其他注释有 @This@AllArguments@Origin@SuperCall。您需要的越少,代理的效率就越高。特别是 @AllArguments 由于其分配要求而非常昂贵。

请注意,在这种情况下,您的字段仅在 super 构造函数调用之后设置。另外,您假设父类(super class)型中有一个默认构造函数。或者,您可以实现自定义 ConstructorStrategy

至于缓存,可以看看 Byte Buddy 的 TypeCache

关于java - 字节好友 : Use new defined field in intercept during construction of class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41586467/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com