Bean Scopes: Singleton, Prototype, and More
Bean Scopes: Singleton, Prototype, and More
A bean's scope decides how many instances the container creates and how long each lives. The default is enough for most code, but picking the wrong scope is a classic source of shared-state bugs in web applications.
Singleton
The singleton scope is the default. The container creates one instance per bean definition and reuses it for every injection point. Singletons are perfect for stateless services, repositories, and configuration objects. They are the right default because they are fast and memory-friendly, but a singleton holding mutable user state will leak that state across requests.
Prototype
Prototype scope asks the container for a fresh instance every time the bean is injected or requested. Use it for stateful, short-lived objects such as per-request UI models or expensive one-off workers. Note that Spring does not manage the full lifecycle of a prototype; cleanup is up to you.
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class Cart {
private final List<Item> items = new ArrayList<>();
// methods that mutate items
}
Web scopes
In web applications, request scope creates a bean per HTTP request, and session scope per user session. These are implemented as scoped proxies when injected into singletons, so the singleton gets a proxy that resolves the current-scoped instance on each call.
Choosing a scope
Ask what the object represents. If it holds no state, use the default singleton. If it holds per-operation state, prefer creating it locally or with prototype scope. Never store request-specific data in a singleton; you will confuse users and yourself.
Key Points
- Singleton (default) reuses one instance per bean definition.
- Prototype creates a new instance per injection or lookup.
- Use scoped proxies when injecting web-scoped beans into singletons.
- Keep request state out of singletons.
- Defaults work for the majority of stateless services.