How long a bean lives and how many instances exist — plus the two scope gotchas that show up almost every exam.
| Scope | Instances | Notes |
|---|---|---|
singleton | One per container | Default. Created eagerly at startup, shared everywhere. |
prototype | A new one every time it's requested/injected | Spring builds it then lets go — see the destruction gotcha below. |
request | One per HTTP request | Web scopes — need a web-aware ApplicationContext. |
session | One per HTTP session | |
application | One per ServletContext | |
websocket | One per WebSocket session |
ApplicationContexts → two instances of the same singleton bean. Classic distractor.
@Component
@Scope("prototype") // or @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Report { ... }
@Bean
@Scope("prototype")
public Report report() { return new Report(); }
For a prototype bean, Spring instantiates it, wires it, runs @PostConstruct… and then
hands it over and forgets about it. The container does not track prototype instances, so:
@PreDestroy, no DisposableBean.destroy(), no custom destroy-method is invoked by the
container for a prototype. Releasing resources is the caller's responsibility. (Init callbacks
like @PostConstruct do still run.)
This is the highest-value scope question. A singleton is created once. So if you
inject a prototype (or request) bean into it the ordinary way, the singleton grabs
one instance at creation time and reuses that same one forever — defeating the point of the shorter scope.
@Service // singleton — created ONCE
public class Dashboard {
@Autowired Report report; // prototype... but frozen to ONE instance here
}
Four correct fixes — each gives the singleton a fresh instance per use instead of one forever:
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS). Spring injects a proxy that fetches a fresh bean on each call.ObjectProvider<Report> (or ObjectFactory) — call .getObject() each time you need one.Provider<Report> — the JSR-330 equivalent, call .get().@Lookup method injection — an abstract/overridable method Spring implements to return a fresh bean.@Autowired is fine. Injecting a
shorter-lived bean into a longer-lived one? You need a proxy or a provider.
Read "The Singleton Scope", "The Prototype Scope" (note the destruction paragraph), and "Scoped Beans as Dependencies" (the proxy solution above).
The prototype-destruction fact and the scoped-into-singleton fix are the two to nail. Options shuffle on every load.