ObjectProvider resolves a dependency on demand from the container rather than fixing the resolved object at the provider’s injection point.
Spring ObjectProvider: deferred resolution without hiding ownership
This lesson uses the downloadable source kit: Java 21, Spring Boot 4.0.8 and its managed Spring Framework 7 dependencies. The version is pinned for repeatable builds.
Resolve at the operation boundary
The kit’s provider resolves prototype ImportBuffer objects twice and verifies separate identity. That is useful when a report operation owns a fresh mutable workspace. It is unnecessary when a stateless collaborator can safely be injected once.
Deferred resolution changes when a lookup can fail. A missing or ambiguous bean can surface during a request instead of startup, so errors need an intentional boundary. Optional configuration should not make a required business dependency disappear silently.
Laziness is narrower than safety
A provider can be queried by a long-lived service, but the resolved object still follows its own scope and lifecycle. Resolving a new buffer does not arrange cleanup for a prototype channel or make that channel safe to share between tasks.
Lazy suppliers have a related timing distinction at the Java level. Avoid computing expensive fallback state before supplying it, and avoid using delayed lookup merely to bypass an unresolved constructor cycle.
Checked source
ObjectProvider<ImportBuffer> provider = context.getBeanProvider(ImportBuffer.class);
ImportBuffer first = provider.getObject();
ImportBuffer second = provider.getObject();
System.out.println(first != second);Test the boundary
Run mvn test in the source-kit directory. CoreBoundaryTest checks the behavior described here. Java excerpts belong to the named source-kit classes; they are not independent source files unless the complete class is shown.
Costs and boundaries
Every prototype resolution allocates a new object. The fixture compares only two small buffers; no throughput or pooling claim follows from that result.
Common Mistakes
- Do not hide a mandatory dependency as optional.
- Resolution does not transfer cleanup to the container for a prototype.
- Deferred lookup does not repair a dependency cycle.
Read next
Spring bean scopes: singleton identity is not thread safety, Java Optional: eager defaults and lazy suppliers, Java generics: invariance, bounds, and type erasure.
