What are Spring bean scopes, and when would you use something other than singleton?
Quick Answer
Singleton (the default) means exactly one shared instance per Spring container, reused for every injection point — appropriate for stateless services. Prototype creates a brand-new instance every time the bean is requested — appropriate for stateful, non-thread-safe objects. Web-aware scopes (request, session, application) tie a bean's lifetime to an HTTP request, session, or the ServletContext respectively, used for holding per-request or per-user state cleanly.
Detailed Answer
Spring bean scope controls how many instances of a bean definition exist and how long each one lives:
singleton(the default): exactly one instance per Spring container, shared by every injection point. Appropriate for stateless components — most@Service/@Repositorybeans fit this naturally, since they hold no per-request mutable state.
@Service // singleton by default
class OrderService { }
prototype: a new instance is created every time the bean is requested (injected or fetched viagetBean()). Appropriate for objects that hold mutable, non-thread-safe per-use state.
@Component
@Scope("prototype")
class ReportBuilder { /* accumulates mutable state per report */ }
request(web-aware): one instance per HTTP request — useful for holding request-scoped data cleanly instead of threading it through method parameters.session(web-aware): one instance per HTTP session — useful for per-user state like a shopping cart.application(web-aware): one instance perServletContext— similar to singleton but scoped to the web application rather than the Spring container specifically (relevant when multiple contexts share a servlet context).
A common gotcha: injecting a prototype-scoped bean into a singleton-scoped bean via normal field/constructor injection only resolves it once, at the singleton's creation time — every subsequent use gets the same prototype instance, defeating the purpose. Fixing this requires a scoped proxy (proxyMode = ScopedProxyMode.TARGET_CLASS) or looking the bean up via ObjectFactory/ObjectProvider each time it's actually needed, so a fresh prototype instance is fetched per use.
Rule of thumb: default to singleton; reach for prototype (or a web-aware scope) only when a bean genuinely needs per-use or per-request/session mutable state.