Reputation: 31
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
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 MethodCall
s as arguments. In these method calls, you would invoke the corresponding getter on the argument value.
Upvotes: 0