skip to content

What is the @DependsOn annotation in Spring and what problem does it solve?

level: juniorimportance: must knowfreq 55%

answer

  1. init-order without an injection edge
  2. names as strings, not a reference
  3. side-effect ordering (cache seed, driver register)
  4. on @Component or @Bean method
  5. 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
java
// 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

for a junior

Know it forces named beans to be created first, that names are strings, and it's for side-effect ordering not injection.

for a middle

Be able to give a concrete use case and contrast it with normal @Autowired-driven ordering.

for a senior

Discuss when it's a smell vs. legitimate, and that misuse hides real coupling.

for a principal

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.

context