@StaticVirtualProxy
Generate a lazy-creation wrapper for an interface at compile time.
@StaticVirtualProxy generates a wrapper class backed by the virtual proxy
strategy infrastructure. The wrapper holds a creation strategy; the real
implementation is built on first use and cached.
Usage
import com.svenruppert.proxybuilder.proxy.generated.annotations.StaticVirtualProxy;
@StaticVirtualProxy
public interface Service {
String work(String input);
}
After compilation, the generator produces ServiceStaticVirtualProxy.
Configure it with a factory and the first call materialises the real instance:
Service proxy = new ServiceStaticVirtualProxy()
.withStrategy(new SingleInstanceCreationStrategy<>(() -> new ServiceImpl()));
proxy.work("hello"); // first call — constructs ServiceImpl, then delegates
proxy.work("again"); // reuses the already-constructed ServiceImpl
What “virtual” buys you
- Lazy construction. The expensive implementation is not built at proxy creation time; it is built when something actually calls a method.
- Thread safety. The default strategy is single-instance and thread-safe. Multiple threads racing on the first call will see one construction and the same cached instance.
- Pluggable lifecycle. Swap in a custom
CreationStrategyfor caching with eviction, per-thread instances, or test fixtures that build a fresh instance each round.
When to prefer this over the runtime version
- You want the compile-time benefits — no reflection, GraalVM-friendly, inspectable generated source.
- You want the proxy to live in a JPMS module and be referenced by other modules without runtime opens.
When the runtime version is fine
- You build the proxy in one place, hand it to one consumer, and never need to inspect the generated source.
See also
- The strategy classes live under
com.svenruppert.proxybuilder.proxy.dymamic.virtual.strategy. - The runtime counterpart: virtual proxies at runtime.