How do you control the order in which auto-configuration classes are applied, and why does ordering matter?
answer
- @AutoConfigureAfter/Before/Order + @AutoConfiguration before/after attrs
- orders auto-configs among themselves only
- all auto-config still runs after user config
- @ConditionalOnBean needs prerequisite registered first
- silent missing bean = ordering bug
basics
~10 sUse the @AutoConfiguration annotation's before/after attributes, or the @AutoConfigureBefore, @AutoConfigureAfter, and @AutoConfigureOrder annotations. Ordering matters because conditions like @ConditionalOnBean depend on whether a prerequisite bean was already registered by an earlier auto-config.
solid answer
~40 sAuto-configurations are applied in a defined order, and some conditions are order-sensitive — notably @ConditionalOnBean, which only sees beans registered by auto-configs processed *before* it. You express ordering with @AutoConfigureAfter / @AutoConfigureBefore (naming other auto-config classes), @AutoConfigureOrder (a numeric Ordered-style priority), or the before/after/beforeName/afterName attributes on @AutoConfiguration itself. For example, an auto-config that adds a bean depending on a DataSource should be @AutoConfigureAfter(DataSourceAutoConfiguration.class) so the DataSource exists when its @ConditionalOnBean evaluates. Note this ordering is *among auto-configurations only*; all of them still run after the application's own user configuration, which is what makes @ConditionalOnMissingBean back-off work. Getting ordering wrong typically shows up as a bean silently not being created because its condition evaluated too early.
code
java · 16 linesimport org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import javax.sql.DataSource;
// Ensure the DataSource is contributed BEFORE this runs, so
// @ConditionalOnBean(DataSource.class) can see it.
@AutoConfiguration(after = DataSourceAutoConfiguration.class)
public class AuditRepositoryAutoConfiguration {
@Bean
@ConditionalOnBean(DataSource.class)
public AuditRepository auditRepository(DataSource dataSource) {
return new JdbcAuditRepository(dataSource);
}
}go deeper
Aware the ordering annotations exist; deep control not expected.
Can name @AutoConfigureAfter/Before and give the DataSource-then-JdbcTemplate example.
Distinguishes auto-config-vs-auto-config ordering from user-vs-auto-config ordering and diagnoses silent missing-bean bugs.
Understands the sorter/tiebreaking, *Name variants for optional targets, and cross-starter default layering.
**Why ordering exists.** Auto-configurations often depend on each other: one contributes a `DataSource`, another wants to build a `JdbcTemplate` from it. Because conditions like `@ConditionalOnBean` are evaluated against 'what has been registered so far,' the *sequence* in which auto-config classes run changes outcomes. Spring Boot therefore gives explicit ordering controls. **The three mechanisms.** - `@AutoConfigureAfter({X.class, ...})` — 'apply me after these auto-configs.' Use when you need beans they contribute. - `@AutoConfigureBefore({Y.class, ...})` — 'apply me before these.' - `@AutoConfigureOrder(int)` — a coarser numeric priority (like `@Order`); lower runs first. Used when there's no specific class to name. - Since Spring Boot 2.7, `@AutoConfiguration` itself has `before`, `beforeName`, `after`, `afterName` attributes, so you can inline the ordering instead of separate annotations. `*Name` variants take String class names, useful when you can't (or don't want to) reference the class directly (e.g. it's optional on the classpath). **The crucial distinction: two different 'orderings.'** 1. **User config vs auto-config:** *All* auto-configurations run **after** all user-defined configuration. This is fixed and is what makes `@ConditionalOnMissingBean` back-off reliable — user beans already exist. You do not (and cannot) reorder auto-config to run before user config. 2. **Auto-config vs auto-config:** *Within* the auto-config phase, the `@AutoConfigureBefore/After/Order` hints set relative order. That's the only thing these annotations affect. **Common failure mode.** You write an auto-config with a `@Bean @ConditionalOnBean(DataSource.class)` method but forget `@AutoConfigureAfter(DataSourceAutoConfiguration.class)`. If yours is processed first, the `DataSource` isn't registered yet, `@ConditionalOnBean` fails, and your bean silently never appears — with no error. The fix is the ordering hint. **How Spring computes the final order.** `AutoConfigurationSorter` topologically sorts the classes using the before/after hints, with `@AutoConfigureOrder`/priority as a tiebreaker and alphabetical name as a final deterministic fallback. The `spring-boot-autoconfigure-processor` can precompute some of this metadata to speed startup. **Gotchas.** - Ordering hints between two auto-configs that both use `@ConditionalOnMissingBean` for the same type decide *who provides the default*; the earlier one wins and the later backs off. - `@AutoConfigureAfter` naming a class that isn't on the classpath is fine (it's just ignored) — prefer the `*Name` string form for optional targets to avoid compile-time coupling. - Don't confuse `@Order`/`@Priority` on beans (affects collection injection order) with `@AutoConfigureOrder` (affects auto-config processing order) — different concerns. **When to use.** Reach for these only when there's a real dependency between auto-configs (bean produced by one, consumed via `@ConditionalOnBean` by another) or when your defaults must layer over/under another starter's. Most single-purpose starters need no explicit ordering.
- If all auto-configs run after user configuration, what does @AutoConfigureAfter actually change?Only the relative order among auto-configuration classes themselves. It doesn't move them before user config. It ensures another auto-config's beans are registered before yours, which matters for @ConditionalOnBean-style conditions.
- When would you use afterName instead of after?When the target auto-config class may not be on the classpath, or you want to avoid a compile-time dependency on it. afterName takes the class name as a String, so it degrades gracefully if that class is absent.
saying these in an interview costs you the question
- Thinking @AutoConfigureBefore can make an auto-config run before user @Configuration
- Confusing @Order on beans with @AutoConfigureOrder on auto-configs
- Expecting @ConditionalOnBean to work without ordering the producing auto-config first
- Believing ordering affects @ConditionalOnMissingBean's user-override behavior