What is the @DependsOn annotation in Spring and what problem does it solve?
answer
- init-order without an injection edge
- names as strings, not a reference
- side-effect ordering (cache seed, driver register)
- on @Component or @Bean method
- XML depends-on attribute
basics
~10 s@DependsOn forces named beans to be created (fully initialized) before the annotated bean. It expresses an initialization-order dependency between beans that have no direct injection relationship.
solid answer
~40 s@DependsOn is a Spring annotation that tells the container: initialize these named beans first, before you create the bean I'm on. You give it bean names as strings. Unlike normal dependency ordering — where wiring bean B into bean A via @Autowired automatically makes Spring create B first — @DependsOn is for cases where there is NO injection between the beans but one still must exist before the other. Classic example: a bean whose @PostConstruct registers a JDBC driver or seeds a cache, and another bean that relies on that side effect having already happened. You can put @DependsOn on a @Component class or on a @Bean factory method. It only controls ordering; it does not inject anything.
code
java · 15 lines// Bean with a side effect other beans rely on, but nobody injects it
@Component("driverRegistrar")
public class DriverRegistrar {
@PostConstruct
void init() {
DriverManager.registerDriver(new com.acme.LegacyDriver());
}
}
// No @Autowired of DriverRegistrar here — only an ordering need
@Component
@DependsOn("driverRegistrar")
public class ReportService {
// by the time this is constructed, the driver is guaranteed registered
}go deeper
Know it forces named beans to be created first, that names are strings, and it's for side-effect ordering not injection.
Be able to give a concrete use case and contrast it with normal @Autowired-driven ordering.
Discuss when it's a smell vs. legitimate, and that misuse hides real coupling.
Frame it as an explicit override of the container's inferred dependency graph, used sparingly for non-injectable side effects.
## What it is `@DependsOn` (package `org.springframework.context.annotation`) is an annotation that forces the Spring container to fully initialize one or more OTHER beans, named by string, before it creates the bean the annotation is placed on. ```java @Component @DependsOn("driverRegistrar") public class ReportService { ... } ``` Here Spring guarantees the bean named `driverRegistrar` is created and fully initialized (constructor + property injection + `@PostConstruct`/`InitializingBean.afterPropertiesSet`/init-method all done) **before** `reportService` begins construction. ## The problem it solves Normally you never need this. When bean A needs bean B, you inject B into A (constructor arg, `@Autowired` field, etc.). Spring's dependency resolution sees that edge and creates B first automatically. The dependency graph IS the injection graph. `@DependsOn` exists for the case where the ordering requirement is real but there is **no injection edge** — the relationship is a *side effect*, not a reference. Examples: - A bean whose `@PostConstruct` seeds a static cache / registers something globally, and a second bean that reads that global state at init time. - A DB-seeding / migration bean (e.g. a manual data-loader) that must run before a bean that queries the data. - A bean that installs a JVM-level hook (security provider, JDBC driver, logging bridge) needed by another bean. Because the second bean doesn't hold a reference to the first, Spring has no way to infer the order — so you state it explicitly. ## Where you can put it - On a `@Component` (or stereotype: `@Service`, `@Repository`, `@Configuration`) class. - On a `@Bean` factory method inside a `@Configuration` class. - The XML equivalent is the `depends-on` attribute: `<bean id="a" depends-on="b"/>`. ## What it does NOT do - It does **not** inject the depended-on bean. You still can't call it unless you also inject/look it up. - It is **not** `@Order` or `@Priority` — those affect the ordering of a *collection* of beans injected together (e.g. a `List<Handler>`), not instantiation timing. `@DependsOn` is purely about *when a bean is instantiated and destroyed*. ## Values You pass bean **names** (the id/name Spring registered, e.g. the method name for a `@Bean`, or the decapitalized class name for a component, or an explicit `@Bean("x")`/`@Component("x")` name). A typo in the name → `NoSuchBeanDefinitionException` at startup. ## Rule of thumb If you can express the need with normal injection, do that — it is self-documenting and refactor-safe. Reach for `@DependsOn` only for genuine side-effect ordering with no reference between the beans.
- Why not just @Autowired the DriverRegistrar into ReportService instead of using @DependsOn?You could, and if ReportService actually needs a reference that's the better, self-documenting choice. @DependsOn is for when there is genuinely no reference — the dependency is a side effect (global/static state) — so injecting would be a fake dependency that adds an unused field just to force ordering.
- What happens if you misspell the bean name in @DependsOn?The container fails fast at startup with a NoSuchBeanDefinitionException (wrapped in a BeanCreationException) because it can't resolve the named depends-on bean.
saying these in an interview costs you the question
- Thinking @DependsOn injects the bean so you can use it (it only orders, doesn't wire).
- Confusing it with @Order/@Priority collection ordering.
- Believing it takes a Class, not a String bean name.