skip to content

Scopes & Bean Lifecycle

Bean scopes from singleton to request, the callbacks Spring fires as a bean is created and destroyed, the post-processors that can rewrite beans and definitions, and how circular references get resolved. Interviewers use this area to find out how deep your model of the container really goes.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

page 2 of 2

When should you use @DependsOn instead of expressing the dependency through normal injection, and why is it usually considered a last resort?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Use @DependsOn only when a bean must exist before another for a side effect but there is no reference to inject. Prefer injection because it's type-safe, self-documenting, and refactor-proof; @DependsOn relies on fragile string names.

open as a page

Explain @Bean's 'inferred' destroyMethod and why an AutoCloseable third-party bean sometimes gets close() called without you configuring anything.

level: seniorimportance: should knowfreq 40%

basics

~10 s

@Bean's destroyMethod defaults to the sentinel "(inferred)": if the bean has a public close() or shutdown() method (or implements AutoCloseable), Spring calls it automatically on shutdown. Set destroyMethod="" to turn this off.

open as a page

Why is a @PreDestroy method on a prototype-scoped bean never called, and what can you do about it?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Spring doesn't manage a prototype's full lifecycle — it creates and hands off the instance without tracking it, so no destroy callback runs. To clean up, do it manually or use a custom BeanPostProcessor/DisposableBeanAdapter yourself.

open as a page

When exactly are SmartLifecycle beans started during context refresh, and how does isAutoStartup() affect that?

level: seniorimportance: should knowfreq 38%

basics

~10 s

At the end of refresh, DefaultLifecycleProcessor.onRefresh() starts every SmartLifecycle bean whose isAutoStartup() returns true, in ascending phase order. Beans with isAutoStartup()==false are skipped and only start on an explicit start() call.

open as a page

What is SmartInitializingSingleton.afterSingletonsInstantiated(), and how does it differ from SmartLifecycle start()?

level: seniorimportance: should knowfreq 34%

basics

~20 s

afterSingletonsInstantiated() is a one-time callback fired after ALL non-lazy singletons are created, so a bean can safely act on the whole set of singletons. It runs during singleton pre-instantiation, before SmartLifecycle start(), which comes later at finishRefresh().

open as a page

How does a session-scoped bean behave across multiple requests and in a clustered/replicated environment?

level: seniorimportance: should knowfreq 45%

basics

~20 s

A session-scoped bean has one instance per HttpSession, shared across that user's requests until the session ends. If sessions are replicated across a cluster, the bean must be Serializable and mutations may not propagate instantly, so avoid non-serializable or heavily mutable state.

open as a page

Why place resource-opening or dependency-validation logic in @PostConstruct rather than the constructor, and how does this interact with AOP proxies and post-processors?

level: principalimportance: should knowfreq 35%

basics

~10 s

In the constructor, field/setter-injected dependencies aren't set yet, and the bean isn't fully post-processed. @PostConstruct runs after injection, so collaborators are available. But it runs before AOP proxying, so self-invocation there isn't advised.

open as a page

How does SmartLifecycle.stop(Runnable callback) enable graceful, phased shutdown, and what is the per-phase timeout?

level: principalimportance: should knowfreq 30%

basics

~20 s

stop(Runnable) lets a bean shut down asynchronously: do your cleanup, then call callback.run() to signal completion. DefaultLifecycleProcessor stops all beans in a phase, then waits up to a timeout (default 30s) for their callbacks before moving to the next phase.

open as a page

What are the subtle edge cases and gotchas when using Aware callbacks (ordering with @PostConstruct, prototypes, doing work in the setter, self-injection)?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

Aware setters run once per instance, before init callbacks, so don't do heavy work in them — just capture the reference and act in @PostConstruct. Context-level Aware needs an ApplicationContext to fire, and calling getBean during the callback can hit half-built beans.

open as a page

You need to enforce that every bean whose name ends in 'Repository' is proxied for metrics and never lazy. How would you implement this with a post-processor, and what pitfalls must you avoid?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

Use a BeanFactoryPostProcessor to iterate bean definitions and, for names ending in 'Repository', set lazy-init false and mark them for proxying. Do metadata changes only in the BFPP; do the actual proxy wrapping in a BeanPostProcessor. Never call getBean in the BFPP.

open as a page

What are the registration, ordering, and early-instantiation pitfalls of BeanPostProcessors?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

BPPs are created early, before normal beans, so any beans a BPP depends on get built early too — potentially before all BPPs are registered, so they may miss post-processing (e.g. not get proxied). Order BPPs with Ordered/PriorityOrdered; BPPs don't post-process each other.

open as a page

As an architect, how do you decide between singleton and prototype (and its provider/proxy plumbing), and what are the concurrency, memory, and testing trade-offs at scale?

level: principalimportance: nice to knowfreq 35%

basics

~20 s

Default to stateless singletons — they're cheap, cached, and thread-safe when immutable. Reach for prototype only when you truly need per-use mutable state or non-shareable objects, and inject them via ObjectProvider. Prefer passing state as method parameters over creating stateful beans.

open as a page

When a bean in a circular dependency is also AOP-proxied, how does Spring ensure the dependent gets the proxy (not the raw target), and when can this throw BeanCurrentlyInCreationException even for a setter/field cycle?

level: principalimportance: nice to knowfreq 30%

basics

~20 s

The level-3 ObjectFactory calls getEarlyBeanReference, which lets AOP post-processors build the proxy early, so a dependent in the cycle receives the proxy. If a different post-processor later wraps the bean into yet another object after the early reference was already exposed, the identities diverge and Spring throws BeanCurrentlyInCreationException.

open as a page

How do you set a depends-on relationship programmatically on a BeanDefinition, and how would you decide between @DependsOn and alternative ordering mechanisms in framework/infrastructure code?

level: principalimportance: nice to knowfreq 18%

basics

~10 s

On a BeanDefinition call setDependsOn(String...) (e.g. via BeanDefinitionBuilder.addDependsOn or an AbstractBeanDefinition), or in XML use depends-on. It's the programmatic equivalent of @DependsOn, used by infrastructure/registrars where annotations aren't available.

open as a page

How do you implement and register a custom Spring scope, and what contract must the Scope interface satisfy?

level: principalimportance: nice to knowfreq 25%

basics

~10 s

Implement org.springframework.beans.factory.config.Scope (get, remove, registerDestructionCallback, resolveContextualObject, getConversationId), then register it via ConfigurableBeanFactory.registerScope(name, scope) — usually in a BeanFactoryPostProcessor — and use @Scope("myScope") on beans.

open as a page

showing 31–45 of 45