@DependsOn names a container-managed bean that must initialize before a dependent bean and, for singletons, outlive it during shutdown.
Spring @DependsOn: force initialization and reverse destruction order
Use it only for an indirect prerequisite
The intake stage needs a registry initialized before intake starts, but the small fixture does not inject the registry directly. @DependsOn names that prerequisite. The checked lifecycle trace is registry start, intake start, intake stop, registry stop. Spring closes the dependent first so its prerequisite still exists during cleanup.
Where one object actually calls another, prefer constructor injection. It states the dependency in Java's type system and gives the application a usable collaborator. Constructor boundaries and cleanup ownership explain those simpler cases.
Ordering cannot repair broken side effects
If registry startup fails, intake does not become usable; the context should fail rather than serve half-initialized traffic. An ordered startup is not a transaction or a distributed readiness guarantee. Runner failure covers another startup cut point.
Checked code
@Bean(initMethod = "start", destroyMethod = "stop")
Stage registry() { return new Stage("registry"); }
@Bean(initMethod = "start", destroyMethod = "stop")
@DependsOn("registry")
Stage intake() { return new Stage("intake"); }Verification boundary
The Maven source kit passes LifecycleAndMvcDispatchContractTest.dependsOnForcesStartupAndReverseShutdownOrder on its local Spring Boot 4 and Java 21 fixture.
Cost and ownership
The fixture records four callbacks in one process. A real startup cost equals the work done by the stages; @DependsOn merely fixes ordering. It does not coordinate multiple replicas or guarantee cleanup after a forced process kill.
Common Mistakes
- Do not use @Order on injected lists to express a bean creation dependency.
- Do not replace an actual constructor dependency with a bean-name string.
- Do not assume shutdown callbacks run after a hard kill.
Read next
Spring @Order on injected lists: execution order is not startup order, Spring constructor injection: required dependencies stay visible, Spring lifecycle cleanup: close container-owned resources, Spring Boot runner failure: reject startup instead of accepting unsafe settings.
