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".

testusage/src/test/java/.../AddPreActionTest.java (inner types) View on GitHub ↗
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

testusage/src/test/java/.../AddPreActionTest.java#test001 View on GitHub ↗
@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.

Edit this page on GitHub ↗