skip to content

Auto-configuration ordering

@AutoConfigureBefore, @AutoConfigureAfter and @AutoConfigureOrder impose a deterministic sequence on auto-configurations that would otherwise be arbitrary. It matters because a conditional on a bean gives different answers depending on who ran first.

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

questions

5

Why does auto-configuration ordering matter, and how does it interact with @ConditionalOnMissingBean?

level: seniorimportance: must knowfreq 45%

answer

  1. Conditions see only already-registered definitions
  2. First-processed defines the bean, others back off
  3. Before => win the default; After => fill the gap
  4. Conditions reliable only on auto-config classes
  5. Definition/eval order != runtime instantiation order

basics

~10 s

Ordering decides which auto-config class is evaluated first. @ConditionalOnMissingBean only sees beans already defined by earlier-processed classes, so the class that runs first defines the bean and later ones back off.

solid answer

~40 s

Auto-config ordering matters because bean-presence conditions are evaluated against the beans defined so far. @ConditionalOnBean and @ConditionalOnMissingBean don't see the whole context at once — they inspect only definitions registered by auto-configurations processed before the current one. So if two classes both offer a DataSource guarded by @ConditionalOnMissingBean, whichever is processed first defines it and the other backs off. That's why Spring's docs say these conditions are reliable only inside auto-config classes with correct @AutoConfigureBefore/@AutoConfigureAfter ordering, and are fragile on user @Configuration. Ordering changes definition/evaluation order, not runtime instantiation order — that stays dependency-driven. To make your bean the winning default, run before the framework class; to only fill a gap, run after it and use @ConditionalOnMissingBean.

code

java · 16 lines
java
// My library wants its DataSource to WIN over Spring Boot's default.
// Processing before the framework class means mine is defined first;
// the framework's @ConditionalOnMissingBean then backs off.
@AutoConfiguration(before = DataSourceAutoConfiguration.class)
public class MyDataSourceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(DataSource.class)
    DataSource dataSource() {
        return buildCustomPooledDataSource();
    }
}

// If instead I only want to provide a fallback when nobody else did,
// I run AFTER and rely on @ConditionalOnMissingBean to fill the gap:
// @AutoConfiguration(after = DataSourceAutoConfiguration.class)

go deeper

for a junior

May not connect ordering to conditions at all.

for a middle

Should know first-processed-wins for @ConditionalOnMissingBean.

for a senior

Should explain the definition-visibility mechanism and the before-to-win / after-to-defer pattern.

for a principal

Should design starter override strategies and warn about the instantiation-vs-definition-order trap and user-@Configuration unreliability.

**The core coupling.** `@ConditionalOnBean` and `@ConditionalOnMissingBean` are evaluated as the container processes configuration classes. Crucially, they can only observe bean **definitions that have already been registered** at the moment the condition is checked. Auto-configuration runs *after* user configuration and in a **sorted, deterministic order**, so within the auto-config phase the presence checks are well-defined — but only if ordering is correct. **The classic scenario.** Suppose `FrameworkAutoConfiguration` defines a `DataSource` with `@ConditionalOnMissingBean(DataSource.class)`, and your library's `MyAutoConfiguration` also defines one with the same guard. - If your class is processed **before** the framework's, yours defines the `DataSource`; the framework's condition then sees it and backs off — your bean wins. - If processed **after**, the framework defines it first and yours backs off. You pick the outcome with `@AutoConfigureBefore(FrameworkAutoConfiguration.class)` (to win) or `@AutoConfigureAfter(...)` (to defer to it and only fill a gap). **Why user @Configuration is different.** The Spring Boot reference explicitly warns that `@ConditionalOnBean`/`@ConditionalOnMissingBean` should generally be used **only on auto-configuration classes**, because user `@Configuration` classes are processed in a phase where global bean visibility is not guaranteed, making presence checks order-sensitive and unreliable. Ordering annotations don't help there because they are honored only for auto-config classes. **Definition order vs instantiation order.** A frequent confusion: ordering controls the sequence in which configuration classes are *evaluated and bean definitions registered*, and therefore which conditions fire. It does **not** dictate the order beans are *instantiated at runtime* — that is determined by the dependency graph (a bean is created when something needs it, respecting `@DependsOn` and constructor injection). So `@AutoConfigureBefore` is about 'who defines what first', not 'who is constructed first'. **Edge cases / gotchas.** - Ordering does not create dependencies. If bean B needs bean A at runtime, express that via injection or `@DependsOn`; `@AutoConfigureAfter` alone won't guarantee A is instantiated first. - `@ConditionalOnMissingBean` without a type sometimes infers from the `@Bean` return type; combined with ordering surprises, this is a common source of 'my bean didn't win' bugs. - A `@ConditionalOnBean` in an earlier-processed class referencing a bean defined by a *later* class will evaluate as absent — order the referencing class *after* the defining one. **When to use.** Whenever you ship a starter that must override, extend, or defer to a framework default. Get the before/after relationship right, then let conditions do the back-off.

  • Does @AutoConfigureAfter(A) guarantee that bean A is instantiated before my bean at runtime?
    No. It only guarantees A's configuration class is processed (definitions registered, conditions evaluated) before yours. Runtime instantiation order follows the dependency graph; use constructor injection or @DependsOn for that.
  • Why does Spring warn against @ConditionalOnMissingBean on user @Configuration classes?
    User @Configuration is processed in a phase without guaranteed global bean visibility, so the presence check is order-sensitive and unreliable. These conditions are designed for the deterministically-ordered auto-configuration phase.

saying these in an interview costs you the question

  • Saying ordering controls runtime bean instantiation order
  • Assuming @ConditionalOnMissingBean sees the fully-populated context regardless of order
  • Using @ConditionalOnBean/@ConditionalOnMissingBean freely on user @Configuration and expecting deterministic results

context

open as a page

How do you control the order in which two Spring Boot auto-configuration classes are applied?

level: juniorimportance: should knowfreq 35%

basics

~10 s

Use @AutoConfigureBefore and @AutoConfigureAfter on the auto-configuration class, naming the other class. They force one to be processed before or after the other, instead of relying on the default order.

open as a page

What is the difference between @AutoConfigureBefore/@AutoConfigureAfter and @AutoConfigureOrder?

level: middleimportance: should knowfreq 40%

basics

~10 s

@AutoConfigureBefore/After express a relationship to a specific named auto-config class. @AutoConfigureOrder is a coarse numeric priority (lower runs earlier, default 0), like @Order, with no reference to any particular class.

open as a page

How did the @AutoConfiguration annotation change ordering and registration in Spring Boot 2.7+, and what are its before/after attributes?

level: seniorimportance: should knowfreq 30%

basics

~10 s

@AutoConfiguration (Boot 2.7+) is a meta-annotation bundling @Configuration(proxyBeanMethods=false). It has before, beforeName, after, afterName attributes so you set ordering inline instead of separate @AutoConfigureBefore/After annotations. Classes are now listed in AutoConfiguration.imports.

open as a page

Explain the deterministic ordering algorithm Spring Boot uses for auto-configurations, including the alphabetical fallback and cycle handling.

level: principalimportance: nice to knowfreq 18%

basics

~10 s

AutoConfigurationSorter first sorts classes alphabetically by name for a stable baseline, then re-sorts by @AutoConfigureOrder, then topologically applies @AutoConfigureBefore/@AutoConfigureAfter. Alphabetical is only a fallback; a cycle in before/after throws an error.

open as a page