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 pageshowhide
explore
- Singleton & Prototype Scopes5 questions
- Web Scopes & Scoped Proxies5 questions
- Init & Destroy Callbacks5 questions
- BeanPostProcessor4 questions
- BeanFactoryPostProcessor & Registry PP5 questions
- *Aware Interfaces5 questions
- Circular Dependencies & Lazy Init6 questions
- Lifecycle, SmartLifecycle & Phased Startup5 questions
- @DependsOn Bean Ordering5 questions
questions
page 2 of 2When should you use @DependsOn instead of expressing the dependency through normal injection, and why is it usually considered a last resort?
basics
~20 sUse @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.
Explain @Bean's 'inferred' destroyMethod and why an AutoCloseable third-party bean sometimes gets close() called without you configuring anything.
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.
Why is a @PreDestroy method on a prototype-scoped bean never called, and what can you do about it?
basics
~20 sSpring 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.
When exactly are SmartLifecycle beans started during context refresh, and how does isAutoStartup() affect that?
basics
~10 sAt 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.
What is SmartInitializingSingleton.afterSingletonsInstantiated(), and how does it differ from SmartLifecycle start()?
basics
~20 safterSingletonsInstantiated() 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().
How does a session-scoped bean behave across multiple requests and in a clustered/replicated environment?
basics
~20 sA 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.
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?
basics
~10 sIn 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.
How does SmartLifecycle.stop(Runnable callback) enable graceful, phased shutdown, and what is the per-phase timeout?
basics
~20 sstop(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.
What are the subtle edge cases and gotchas when using Aware callbacks (ordering with @PostConstruct, prototypes, doing work in the setter, self-injection)?
basics
~20 sAware 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.
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?
basics
~20 sUse 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.
What are the registration, ordering, and early-instantiation pitfalls of BeanPostProcessors?
basics
~20 sBPPs 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.
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?
basics
~20 sDefault 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.
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?
basics
~20 sThe 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.
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?
basics
~10 sOn 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.
How do you implement and register a custom Spring scope, and what contract must the Scope interface satisfy?
basics
~10 sImplement 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.
showing 31–45 of 45