Bean Scopes
Master Spring bean scopes — singleton, prototype, request, session — and understand when each scope is appropriate and the common pitfalls of mixing scopes.
Last reviewed: January 2025
🔍 What Is It?
Bean scope controls the lifecycle and number of bean instances created by the IoC container.
Available scopes:
singleton (default)
- →One instance per ApplicationContext
- →Shared across all threads and all injection points
- →Created at startup (eager) or first use (lazy)
- →Destroyed when context closes
prototype
- →New instance created every time the bean is requested
- →Spring does NOT manage its destruction (@PreDestroy not called)
- →Use for stateful objects that must not be shared
request (web apps only)
- →One instance per HTTP request
- →Created when request starts, destroyed when it ends
- →Thread-safe by design (one request = one thread = one bean)
session (web apps only)
- →One instance per HTTP session
- →Lives as long as the user's session
- →Stored in HTTP session, serializable
application (web apps only)
- →One instance per ServletContext (essentially singleton for web apps)
Custom scopes
- →Spring allows defining custom scopes (e.g., Spring Batch defines job and step scopes)
🎯 Why Do We Need It?
Different objects have different lifecycle requirements:
- →A
UserServiceis stateless — one singleton instance handles all users safely - →A
ShoppingCartis stateful per user — needs session scope - →A
ReportGeneratoraccumulates state during generation — needs prototype scope - →A
RequestContextholds per-request data — needs request scope
Using the wrong scope causes bugs: a singleton with mutable state is a concurrency disaster; a new prototype for every call is wasteful if the object is stateless.
🏗️ What Happens in Real Projects?
In enterprise Spring Boot apps:
- →99% of beans are singleton — services, repositories, controllers, config beans
- →Prototype used for: batch job processors, report builders, objects with mutable state
- →Request scope used for: request ID tracking, per-request audit context, security context holders
- →Session scope used for: shopping carts, user preferences, wizard/multi-step form state
⚙️ How It Works
Singleton bean:
Spring creates one instance and returns the same reference every time it's injected or looked up. This is why all singleton beans MUST be thread-safe (stateless or using thread-safe data structures).
Prototype bean injected into singleton:
This is the classic scope mismatch problem. If a singleton bean has a prototype dependency, Spring injects the prototype ONCE at creation time. The singleton holds a reference to that one prototype instance forever — defeating the purpose of prototype scope.
Solution: ObjectProvider<T>
@Service
public class ReportService {
private final ObjectProvider<ReportGenerator> generatorProvider;
public void generateReport(ReportRequest request) {
ReportGenerator generator = generatorProvider.getObject(); // new instance each call
generator.generate(request);
}
}💻 Example
Bean Scopes in Practice — Singleton services, prototype processors, and request-scoped context.
🤔 Common Confusions
❓ Can I inject a request-scoped bean into a singleton?
Yes, but Spring injects a proxy, not the actual bean. The proxy delegates to the real request-scoped bean for the current request. This is why @RequestScope beans work when injected into singletons — Spring creates a scoped proxy automatically. Add @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS) if needed.
❓ Are singleton beans thread-safe?
Singleton beans are shared across all threads, but Spring doesn't make them thread-safe for you. YOU must ensure thread safety. The key rule: don't store mutable instance state in singleton beans. Keep all state in local variables (method-scoped) or use thread-safe data structures (ConcurrentHashMap, AtomicLong). Stateless services are naturally thread-safe.
❓ When should I use prototype scope?
Rarely. Use prototype when: (1) the bean has mutable state that must not be shared, (2) each caller needs an independent instance, (3) the object is expensive to share due to state. Most enterprise beans are stateless singletons. If you find yourself reaching for prototype, first ask if the state should be in a method parameter instead.
🚨 Common Production Issues
Singleton bean with mutable instance fields causing race conditions under concurrent requests
Prototype bean injected directly into singleton — only one instance created, scope not working
Session-scoped bean not serializable — causes issues with distributed sessions (Redis)
Request-scoped bean accessed outside of request (e.g., in @Async method) — use RequestAttributes
Memory leak from prototype beans holding resources — Spring doesn't call @PreDestroy on prototypes
✅ Best Practices
Default to singleton — only use other scopes when you have a specific reason
Never store mutable request-specific state in singleton beans
Use ObjectProvider<T> to correctly inject prototype beans into singletons
Ensure session-scoped beans implement Serializable for distributed session support
Use request scope for per-request context (trace IDs, user context, audit info)
🏛️ Architect's Note
The most common production bug I see with bean scopes is storing user-specific data in singleton service fields. A developer stores the "current user" in a @Service field, and it works fine in testing (single user). In production with concurrent requests, users see each other's data. Rule: singleton beans must be stateless. All request-specific state goes in method parameters, ThreadLocal, or request-scoped beans.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
↗ Where this topic fits
Spring Boot Technology Guide
Return to the Spring Boot learning hub.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Spring Boot references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Spring Boot learning path
Browse the full Spring Boot topic collection and learning order on SplashRide.
Spring Boot Interview Prep
Practice Spring Boot interview questions and scenario-based answers.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
IoC Container
Understand the Spring IoC Container — the heart of Spring that manages object creation, dependency wiring, and bean lifecycle in every enterprise application.
Dependency Injection
Master Spring's three DI styles — constructor, setter, and field injection — and understand why constructor injection is the only correct choice for production code.