JeffreyH
JeffreyH

Reputation: 31

Invoke a method based on argument with byte buddy

I have the following interface

public interface DatabaseClient {
    void save(Entity entity, Consumer<Long> callback);
    void load(long id, Consumer<Entity> callback);
}

and an implementation of this interface called DatabaseClientImpl.

I used byte buddy to subclass the interface DatabaseClient. The generated class will delegate each method to a class which creates an Invocation record.

public record Invocation(Method method, Object[] parameters) {}

Invocation objects will later be passed to an abstract class ProxyHandler which implements java.util.function.Consumer<Invocation>. What I'm now trying to achieve is to subclass ProxyHandler and call the method stored in Invocation with the parameters on an instance ofDatabaseClientImpl.

This is what I've done so far..

public <T> void register(Class<T> intf, T service) throws ReflectiveOperationException {
    ProxyHandler proxyHandler = new ByteBuddy()
        .subclass(ProxyHandler.class)
        .method(isAbstract())

        // todo intercept and dynamically call method
        //.intercept(MethodCall.invoke(loadMethod)
        //    .on(service)
        //    .with(1L, callback))

        .make()
        .load(ProxyHandler.class.getClassLoader())
        .getLoaded()
        .newInstance();

    proxyHandler.accept(new Invocation(...));
}

public static abstract class ProxyHandler implements Consumer<Invocation> {
}

Generally, the approach using MethodCall works but I only added it for testing. Since there are other interfaces than DatabaseClient this rather static approach isn't going to work.

So, is there any way to delegate calls to DatabaseClientImpl based on the properties of Invocation?

Upvotes: 0

Views: 278

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

Reputation: 44042

This is a problem you can better solve with reflection/method handles using a simple Proxy, I would assume as you do not need to subclass. You can of course use Byte Buddy, and you can use MethodCall and supply additional MethodCalls as arguments. In these method calls, you would invoke the corresponding getter on the argument value.

Upvotes: 0

Related Questions