Spring BootBean Scopesintermediate
Updated:

Spring Boot Bean Scopes Interview Questions and Answers

7 min read

Bean scope questions Spring interviewers love — singleton vs prototype, the web scopes, why the default is singleton, and how to fix a singleton holding a prototype.

TL;DR – Quick Answer

Spring Boot bean scope interviews test whether you know the six scopes and when each applies: singleton (one instance per container, the default), prototype (a new instance per request for the bean), and the web scopes request, session, application and websocket. The high-value follow-up is the singleton-holding-prototype problem and its fixes — @Lookup, ObjectProvider, or a scoped proxy with proxyMode = TARGET_CLASS.

On This Page

Bean scope questions look simple until the follow-ups arrive. Naming singleton and prototype earns nothing on its own; interviewers are checking whether you understand what "one instance per container" really means, why a singleton shared across threads is a concurrency risk, and how to correctly get a fresh prototype from inside a singleton. This set covers the scope questions asked in intermediate rounds, each with a spoken answer and the trap that usually follows.

Why interviewers ask about bean scopes

Scope decides how many instances of a bean exist and how long they live, which directly controls state, memory and thread safety. Choosing the wrong scope produces some of the most confusing bugs in Spring — shared mutable state on a singleton, or a prototype that mysteriously never changes. Interviewers ask because scope reveals whether you think about lifetime and sharing, not just wiring.

Q1. What bean scopes does Spring Boot support?

Two scopes exist in any Spring application — singleton (one instance per container, the default) and prototype (a new instance every time the bean is requested). A web application adds four more: request, session, application and websocket.

You set a non-default scope with @Scope. The names describe the lifetime: a request-scoped bean lives for one HTTP request, a session-scoped bean for one user session, an application-scoped bean for the ServletContext lifetime, and a websocket-scoped bean for a WebSocket session.

@Component
@Scope("prototype")
class ShoppingCart { /* a new instance per injection point / lookup */ }

Interview note: Follow-up: "which of these need a web context to work?" Request, session, application and websocket — asking for them outside a web application throws, because there is no request or session to bind the bean to.

Q2. What is the difference between singleton and prototype scope?

A singleton is created once per container, cached, and shared by every dependent — the same object everywhere. A prototype is created fresh each time it is requested or injected, so each holder gets its own instance. Singletons are eagerly created at startup by default; prototypes are created lazily on demand.

The lifecycle difference matters in interviews: the container manages a singleton fully, including destroy callbacks on shutdown, but only manages a prototype up to creation — it never runs destroy callbacks for prototypes. Use singleton for stateless services, prototype for objects that carry per-use mutable state.

Interview note: Trap: "does the container call @PreDestroy on a prototype?" No — once it hands over the instance it keeps no reference, so cleanup is the caller's job. Linking scope to the destroy-callback rule signals real depth.

Q3. Is a Spring singleton the same as the singleton design pattern?

No. The Gang of Four singleton guarantees one instance per JVM/classloader, enforced in the class itself. A Spring singleton is one instance per Spring ApplicationContext — start two contexts and you get two instances. Spring's scope is about container-managed sharing, not JVM-wide uniqueness.

This distinction is a favourite because candidates parrot "singleton means one object" without qualifying "per container." In tests or multi-context setups the difference becomes visible, and knowing it shows you understand where the guarantee actually holds.

Interview note: Follow-up: "so how many instances if two contexts each define the bean?" Two — one per context. The uniqueness is scoped to the container, full stop.

Q4. Are singleton beans thread-safe?

No. Spring shares one singleton instance across every thread, but it does nothing to synchronize access. Any mutable instance field on a singleton is a shared-state race condition. The standard practice is to keep singletons stateless, or to guard mutable state explicitly.

This is why Spring services and repositories are typically stateless, pushing per-request data through method parameters or request-scoped beans instead of fields. When a singleton genuinely needs mutable state, use thread-safe constructs or scope the state to the request.

@Service
class CounterService {
    private int count;                 // BUG: shared mutable state on a singleton
    public void increment() { count++; }   // not atomic, races across threads
}

Interview note: Trap: "how do you make per-request state safe on a singleton service?" Do not store it on the singleton — pass it as a parameter, or inject a request-scoped bean via a scoped proxy. Adding a lock is usually the wrong answer for request data.

Q5. What is the singleton-holding-prototype problem, and how do you fix it?

A singleton is created once, so any prototype injected into it as a normal field is resolved exactly once and cached with the singleton — you keep getting the same prototype instance, silently defeating prototype scope. The fixes are @Lookup method injection, an injected ObjectProvider<T> whose getObject() you call per use, or a scoped proxy with proxyMode = TARGET_CLASS.

The root cause is timing: injection happens when the singleton is built, and the singleton is only built once, so the prototype is never re-requested. Each fix defers resolution to call time instead of injection time.

@Component
class OrderProcessor {
    @Autowired
    private ObjectProvider<ShoppingCart> cartProvider;   // prototype provider

    void process() {
        ShoppingCart cart = cartProvider.getObject();    // fresh prototype each call
    }
}

Alternatively, mark the prototype with a scoped proxy so Spring injects a proxy that fetches a new target on each method call:

@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
class ShoppingCart { }

Interview note: Follow-up: "which fix would you pick?" ObjectProvider for explicit, readable lazy access; a scoped proxy when you want callers to use the bean transparently; @Lookup for a container-generated factory method. All three move resolution to call time — that is the point.

Q6. What is a scoped proxy and when do you need one?

A scoped proxy is a lightweight stand-in that Spring injects in place of a shorter-lived bean. When a longer-lived bean (a singleton) depends on a shorter-lived one (request, session, or prototype), the proxy forwards each call to the correct current instance. Without it, the shorter-lived bean would be resolved once and frozen.

You enable it with proxyMode = ScopedProxyMode.TARGET_CLASS (CGLIB proxy of the class) or INTERFACES (JDK proxy of its interfaces). It is exactly what makes injecting a request-scoped bean into a singleton controller work correctly.

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
class RequestContext { /* one real instance per HTTP request, behind a proxy */ }

Interview note: Trap: "why does a request-scoped bean need a proxy to be injected into a singleton?" The singleton exists once, at startup, when no request exists — the proxy defers to the live request instance on every call, so there is a real bean by the time a method is invoked.

Q7. What are the web scopes and what shortcut annotations exist?

request lives for one HTTP request, session for one user session, application for the ServletContext, and websocket for a WebSocket session. Spring provides shortcut annotations @RequestScope, @SessionScope and @ApplicationScope that combine @Scope with a sensible default proxy mode so you do not spell out the value and proxyMode by hand.

These shortcuts are the idiomatic way to declare web scopes because they enable a scoped proxy automatically, which is almost always what you want when injecting into a singleton.

@Component
@RequestScope                         // == @Scope(value="request", proxyMode=TARGET_CLASS)
class UserRequestInfo { }

Interview note: Follow-up: "difference between session and application scope?" Session is per user session — each logged-in user gets their own instance; application is one instance for the whole ServletContext, shared across all users and sessions.

Q8. Why is singleton the default scope, and when would you change it?

Singleton is the default because most beans — services, repositories, controllers, configuration — are stateless, so one shared instance is correct and cheapest in both memory and construction time. You change scope only when a bean must carry state that cannot be shared: prototype for per-use mutable objects, request/session for per-request or per-user state.

The design principle behind the default is "stateless by default, scoped by exception." If you find yourself reaching for prototype constantly, it usually signals state that should have been a method parameter or a dedicated request-scoped holder.

Interview note: Trap: "you made a service prototype to avoid a threading bug — is that right?" Usually no. The fix is to remove the mutable field from the singleton, not to multiply instances. Prototype hides the smell rather than removing it.

How to prepare

Build the singleton-holding-prototype demo from Q5 and prove it to yourself: inject a prototype as a plain field, print its identity hash across calls, watch it stay identical, then switch to ObjectProvider and watch it change. That five-minute experiment turns the most-asked scope follow-up into something you have seen rather than memorized. Do the same with a request-scoped bean behind a proxy injected into a singleton controller.

Ground the container concepts on the Spring Boot learning path, and read this alongside bean lifecycle and dependency injection — scope, lifetime and injection are almost always tested as a single thread of questions. A mock interview that pushes from "name the scopes" into "now fix this singleton" is the quickest way to find and close the gap in your explanation.

Frequently Asked Questions

What are the bean scopes available in Spring Boot?
Singleton and prototype are available in any Spring application. In a web application you additionally get request, session, application and websocket scopes. Singleton is the default, meaning one shared instance per Spring container.
Is a singleton bean one per JVM?
No — a singleton is one instance per Spring container (ApplicationContext), not one per JVM. If an application starts two contexts, each gets its own singleton instance. Conflating the Spring singleton with the Gang of Four singleton pattern is a common interview mistake.
What is the singleton-holding-prototype problem?
A singleton is created once, so a prototype injected into it as a field is also resolved once and never refreshed — you get the same prototype instance every time, defeating the scope. The fixes are @Lookup method injection, injecting an ObjectProvider and calling getObject() per use, or a scoped proxy with proxyMode = TARGET_CLASS.
Are singleton beans thread-safe?
Spring does not make singletons thread-safe; because one instance is shared across all threads, mutable instance state is a race condition. Keep singletons stateless, or guard shared mutable state yourself. This is why services are usually stateless in Spring applications.
Why is singleton the default scope in Spring?
Most beans — services, repositories, controllers — are stateless and can be safely shared, so creating one instance saves memory and construction cost. Sharing a single stateless instance is the efficient default, and prototype or web scopes are opt-in for the cases that genuinely need per-use or per-request state.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — See the Java Full Stack course in Hyderabad

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us