Wrap an interface
The minimum viable runtime proxy — give the builder an interface and an implementation, get a proxy back.
Problem
You have an interface and a concrete implementation. You want a proxy you can hand to consumers of the interface, with no surprises in observed behaviour — the proxy must return the same results as the real instance.
This is the smallest possible runtime proxy, used as a sanity check and as the starting point for everything else.
Files involved
The interface and the implementation
public interface InnerDemoInterface {
String doWork();
}
public class InnerDemoClass implements InnerDemoInterface, HasLogger {
public InnerDemoClass() {
logger().info("InnerDemoClass = init {}", System.nanoTime());
}
@Override
public String doWork() {
return "InnerDemoClass.doWork()";
}
}From proxybuilder tag 00.10.00
InnerDemoClass is a plain implementation of InnerDemoInterface. The
HasLogger mixin gives it a logger; everything else is standard Java.
Wrapping with the builder
@Test
public void testCreateBuilder02() throws Exception {
final DynamicProxyBuilder<InnerDemoInterface, InnerDemoClass> builder = DynamicProxyBuilder.createBuilder(
InnerDemoInterface.class,
InnerDemoClass.class,
CreationStrategy.NONE);
final InnerDemoInterface demoLogic = builder.build();
Assertions.assertNotNull(demoLogic);
final InnerDemoClass original = new InnerDemoClass();
Assertions.assertEquals(demoLogic.doWork(), original.doWork());
}From proxybuilder tag 00.10.00
DynamicProxyBuilder.createBuilder(...) takes the interface class, the
implementation class and a CreationStrategy. CreationStrategy.NONE means
“create the wrapped instance immediately” — no laziness. .build() returns
a proxy that satisfies the interface and forwards every call to the real
instance.
The two assertions in the test prove the contract: the proxy is not null,
and proxy.doWork() returns the same string as original.doWork().
Run it
./mvnw -pl testusage test -Dtest=DynamicProxyBuilderTest#testCreateBuilder02
The test passes silently — there is no expected console output beyond Maven’s “BUILD SUCCESS”. For visible output of a proxy in action, see Add a pre-action.
What to take away
- The proxy implements the interface — consumers cannot tell the difference.
- The builder is a single fluent chain; you add behaviour by calling more
builder methods before
.build(). - This minimal form has no observable side effect. It is the foundation — pre-actions, security rules and metrics layer on top.