core

Bean Lifecycle & Scopes

Control when beans are created, initialized, and destroyed — and how many instances exist.

A Spring bean is not just constructed and forgotten — it moves through a defined lifecycle from instantiation, through dependency injection and initialisation callbacks, to destruction when the context closes. Knowing this sequence lets you hook in setup and teardown logic at the right moment, and understanding scopes tells you how many instances exist and how long each lives.

A singleton is the office coffee machine — one for everyone. A prototype is a paper cup — fresh each time. Request scope is a desk for the duration of one visitor.

Key Concepts

1
After Spring instantiates a bean and injects its dependencies, it runs initialisation callbacks in order: methods annotated @PostConstruct, then afterPropertiesSet if the bean implements InitializingBean, then any custom initMethod. This is where you open resources, validate configuration, or warm a cache — safely, because all dependencies are now wired. At shutdown, the mirror image runs: @PreDestroy, then DisposableBean.destroy, then a custom destroyMethod, giving you a place to close connections and flush buffers. Scope determines instance count and lifetime: the default singleton means one shared instance per container, created eagerly at startup; prototype creates a fresh instance on every injection or lookup; and web scopes request and session tie a bean's life to an HTTP request or user session.
@PostConstructafterPropertiesSetInitializingBeaninitMethod@PreDestroy
2
The classic interview trap lives at the intersection of scopes: injecting a shorter-lived bean (prototype or request) into a long-lived singleton. Because the singleton is wired once at startup, it captures a single instance of the inner bean and never asks for a new one, defeating the shorter scope. The fix is a scoped proxy or a Provider/ObjectFactory lookup. It is also worth knowing that Spring does not manage the full lifecycle of prototype beans — it creates and hands them over but does not call their destroy callbacks, so cleanup is the caller's responsibility.
ProviderObjectFactory