A lazy injection-point proxy can let an eager consumer start without constructing its lazy target until a method is invoked.
Spring @Lazy injection point: defer a dependency behind a proxy
Mark both sides of the boundary deliberately
The fixture marks PricingIndex as a lazy bean and the PricingService constructor parameter as lazy. Context refresh builds the service but not the target index. Calling rate through the injected interface then builds the index once and returns 47. The first version of this fixture marked only the injection parameter; because the target bean was otherwise eager, Spring had already constructed it during refresh. That failed check is the useful edge case.
An interface keeps the proxy boundary straightforward. Avoid relying on proxying a final class or a method that cannot be intercepted. Bean-level laziness establishes when a target itself is eligible for delayed creation; service proxies are a separate mechanism.
First call can fail
A proxy does not make the remote dependency healthy. It moves construction and any associated error to the first method invocation. If availability matters before traffic, use a startup or readiness check that exercises the dependency intentionally, then bound first-use latency and failure handling.
Checked code
@Bean @Lazy PricingIndex pricingIndex() {
return new LoadedPricingIndex();
}
@Bean PricingService pricingService(@Lazy PricingIndex index) {
return new PricingService(index);
}Verification boundary
The Maven source kit passes LifecycleAndMvcDispatchContractTest.lazyInjectionProxyDelaysAnEagerServicesDependency on its local Spring Boot 4 and Java 21 fixture.
Cost and ownership
The proxy adds one dispatch indirection and defers construction cost to first call. The local test checks exactly one construction after method invocation; it does not measure proxy overhead or prove safe behavior if first use occurs concurrently on a busy service.
Common Mistakes
- Do not mark only the parameter lazy and assume an otherwise eager target is unbuilt.
- Do not use a lazy proxy to suppress required startup checks.
- Do not assume every final or inaccessible method can be proxied.
Read next
Spring @Lazy singleton: failure moves from context refresh to first use, Spring bean scopes: singleton identity is not thread safety, Spring readiness: report an unavailable dependency without forcing liveness failure, Spring AOP proxies: self-invocation bypasses proxy advice.
