如何使用 bytebuddy 跟踪对象更改?

问题描述 投票:0回答:1

我正在尝试编写类似于工作单元的东西来跟踪更改,尽管它非常特定于某些生成的代码。

我有以下 ByteBuddy 代码

    private Class<? extends Group> getTrackedClass(GroupChangeTrackingProxy trackingProxy) {
        return new ByteBuddy()
                .subclass(Group.class)
                .method(ElementMatchers.isSetter())
                .intercept(InvocationHandlerAdapter.of(new GroupChangeTrackingProxy()))
                .make()
                .load(CustomerPlatformGroupsRepositoryImpl.class.getClassLoader())
                .getLoaded();
    }
public class GroupChangeTrackingProxy implements InvocationHandler {

    private final Logger log = LogManager.getLogger(GroupChangeTrackingProxy.class);
    private final GroupModifications target = new GroupModifications();
    private final AtomicBoolean tracking = new AtomicBoolean(false);

    public GroupModifications getTarget() {
        return target;
    }

    public void setTrack(boolean bool) {
        this.tracking.setPlain(bool);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {

        if (tracking.get()) {
            var match = ReflectionUtils.findMethod(GroupModifications.class, method.getName());
            if (match != null) {
                ReflectionUtils.invokeMethod(match, target, args);
                log.debug(
                        "tracking: '{}.{}({})'",
                        () -> proxy.getClass().getSimpleName(),
                        method::getName,
                        () -> args);
            }
        }
// RECURSIVE!!!!
        ReflectionUtils.invokeMethod(method, proxy, args); 

        return null; // should be void methods anyways
    }
}

我们必须将返回的信息复制到我们跟踪的代理中,然后开始跟踪

    private Group track(Group value) {
        var tracker = new GroupChangeTrackingProxy();
        var clazz = getTrackedClass(tracker);

        var tracked = createInstanceOf(clazz);
        this.copier.copy(value, tracked);
        tracker.setTrack(true);
        return tracked;
    }

这个实现的问题是它最终是一个递归调用。我可以避免使用 spring

ReflectionUtils
InvocationHandler
,但我找不到从 Byte Buddy 获取方法名称的方法。

如何在没有递归问题的情况下做到这一点?

java byte-buddy
1个回答
0
投票

我在这个问题中找到了答案

本质上就是这些注释

    public void invoke(
            @This Object proxy, @SuperMethod Method method, @AllArguments Object[] args) 

然后更改 bytebuddy 的设置方式

.intercept(MethodDelegation.to(new GroupChangeTrackingProxy()))
© www.soinside.com 2019 - 2024. All rights reserved.