skip to content

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

level: juniorimportance: should knowfreq 35%

answer

  1. Before / After / Order trio
  2. Order = lower runs first, like @Order
  3. @AutoConfiguration(before=, after=) since 2.7
  4. Only on auto-config classes in .imports
  5. Matters for ConditionalOnMissingBean back-off

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.

solid answer

~30 s

Auto-configuration classes are ordered so Spring processes them in a predictable sequence. You influence that with three annotations placed on the auto-config class: @AutoConfigureBefore(X.class) says 'process me before X', @AutoConfigureAfter(X.class) says 'process me after X', and @AutoConfigureOrder(n) gives a coarse priority (lower runs earlier, like @Order). Since Spring Boot 2.7 you can instead pass before=/after= directly to the @AutoConfiguration meta-annotation. Ordering matters mainly because conditions like @ConditionalOnMissingBean look at what has already been defined, so the class that runs first 'wins'. These annotations only work on real auto-configuration classes (listed in the AutoConfiguration.imports file), not on ordinary user @Configuration classes.

code

java · 19 lines
java
// Legacy style: separate ordering annotations
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@AutoConfigureBefore(JpaAutoConfiguration.class)
@AutoConfigureOrder(10)
public class MyPersistenceAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    MyRepository myRepository(DataSource ds) { return new MyRepository(ds); }
}

// Modern style (Spring Boot 2.7+): attributes on @AutoConfiguration
@AutoConfiguration(after = DataSourceAutoConfiguration.class,
                   before = JpaAutoConfiguration.class)
public class MyPersistenceAutoConfiguration2 {
    @Bean
    @ConditionalOnMissingBean
    MyRepository myRepository(DataSource ds) { return new MyRepository(ds); }
}

go deeper

for a junior

Should know the three annotations exist and roughly what before/after mean.

for a middle

Should distinguish relationship-based before/after from priority-based @AutoConfigureOrder and know the 2.7+ attribute form.

for a senior

Should tie ordering to conditional back-off semantics and know it only applies to auto-config classes.

for a principal

Should reason about the sorter stages, cycles, and when a starter genuinely needs explicit ordering vs relying on conditions.

**What auto-configuration is.** Spring Boot ships hundreds of *auto-configuration* classes — special `@Configuration` classes that conditionally define beans (a `DataSource`, a `RestTemplate`, etc.) if certain conditions hold. They are discovered from a registration file: `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` (Spring Boot 2.7+; older versions used the `EnableAutoConfiguration` key in `META-INF/spring.factories`). **Why order matters.** Many auto-config classes use conditions such as `@ConditionalOnBean`, `@ConditionalOnMissingBean`, or `@ConditionalOnClass`. `@ConditionalOnMissingBean` only 'sees' beans that were *already defined by earlier-processed auto-configurations*. So if class A defines a bean and class B backs off when that bean exists, A must be processed before B. Ordering does **not** change runtime bean *instantiation* order (that is driven by dependency injection); it changes the order in which the *configuration classes are evaluated and their bean definitions registered*. **The three ordering annotations.** - `@AutoConfigureBefore(SomeAutoConfiguration.class)` — 'apply me before that class.' Also has a `name`/`beforeName` string form for classes you cannot reference directly. - `@AutoConfigureAfter(SomeAutoConfiguration.class)` — 'apply me after that class.' Same string form. - `@AutoConfigureOrder(int)` — a coarse priority analogous to `@Order`: **lower value = earlier**, default is `0`. It is a global-ish tiebreaker, not a relationship to a specific class. **The @AutoConfiguration attributes (2.7+).** The `@AutoConfiguration` meta-annotation (which itself bundles `@Configuration(proxyBeanMethods = false)`) exposes `before`, `beforeName`, `after`, `afterName` attributes, so you can write `@AutoConfiguration(after = DataSourceAutoConfiguration.class)` instead of stacking a separate `@AutoConfigureAfter`. **Deterministic ordering vs alphabetical fallback.** `AutoConfigurationSorter` produces a stable order in three stages: (1) sort by fully-qualified class name **alphabetically** — this makes the starting order deterministic regardless of file/classpath discovery order; (2) re-sort by `@AutoConfigureOrder`; (3) apply the `@AutoConfigureBefore`/`@AutoConfigureAfter` constraints via a topological sort. So alphabetical order is only the *fallback* used when nothing else constrains two classes — you should never rely on it deliberately. **Gotchas.** - These annotations are honored **only on auto-configuration classes** (those in the imports file). Putting `@AutoConfigureAfter` on a regular user `@Configuration` does nothing. - Referencing a class that is not itself an auto-configuration in `before`/`after` has no effect. - A **cycle** among before/after constraints throws an error at startup. - Prefer expressing an explicit before/after relationship over `@AutoConfigureOrder` when you actually depend on a specific other class — order values are brittle. **When to use.** Almost never in application code; mostly when authoring a starter/library whose beans must be defined before or after a framework auto-config (e.g., you contribute a `DataSource` customization that must run after `DataSourceAutoConfiguration`).

  • Do these annotations work on a normal @Configuration class in my app?
    No. They are only honored on auto-configuration classes registered in the AutoConfiguration.imports file (or legacy spring.factories). On an ordinary user @Configuration they are ignored.

saying these in an interview costs you the question

  • Claiming @AutoConfigureAfter changes the runtime bean instantiation order (it changes config-class processing/definition order, not DI graph order)
  • Thinking these annotations work on any @Configuration class

context