Add a pre-action
Run a callback before every method invocation on a runtime proxy.
Problem
You have an interface and an implementation, and you want a callback to run before every method call — for argument logging, for instrumentation, for debugging, for a “what is going on?” trace. You do not want to touch the implementation; the wrapping should be invisible to the calling code.
The runtime builder solves this with .addIPreAction(...).
Files involved
The interface and the implementation
The test declares both as inner types in the same file. The implementation
returns its input concatenated with the string "impl".
public interface DemoService {
String doWork(String txt);
}
public static class DemoServiceImplementation implements DemoService {
@Override
public String doWork(final String txt) {
return txt + "impl";
}
}From proxybuilder tag 00.10.00
Wrapping with a pre-action
@Test
public void test001() throws Exception {
final DemoService build = DynamicProxyBuilder
.createBuilder(DemoService.class, DemoServiceImplementation.class, CreationStrategy.NONE)
.addIPreAction((original, method, args) -> {
logger().info("original = {}", original);
})
.build();
Assertions.assertEquals("hhimpl", build.doWork("hh"));
}From proxybuilder tag 00.10.00
The pre-action receives three arguments: the original instance, the method being called, and the arguments array. Here it just logs the original instance reference, but you have full reflective access to the method and the arguments.
The proxy then delegates to DemoServiceImplementation.doWork("hh"), which
returns "hhimpl". The assertion proves the return value is unchanged — the
pre-action ran, but it did not interfere with the result.
Run it
./mvnw -pl testusage test -Dtest=AddPreActionTest#test001
Maven prints the pre-action’s log line during the test:
... AddPreActionTest - original = junit.com.svenruppert.proxybuilder.proxy.dynamic.AddPreActionTest$DemoServiceImplementation@…
Composing more than one pre-action
addIPreAction can be called multiple times. The actions run in
registration order, before the real implementation. The same is true for
addIPostAction for “after” hooks. Combine the two to bracket every call:
DynamicProxyBuilder
.createBuilder(Service.class, new ServiceImpl())
.addIPreAction(before)
.addIPostAction(after)
.build();
For the equivalent at compile time — annotation-driven, no reflection at runtime — see the custom processor method decorators.