How do you control the order in which two Spring Boot auto-configuration classes are applied?
answer
- Before / After / Order trio
- Order = lower runs first, like @Order
- @AutoConfiguration(before=, after=) since 2.7
- Only on auto-config classes in .imports
- Matters for ConditionalOnMissingBean back-off
basics
~10 sUse @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 sAuto-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// 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
Should know the three annotations exist and roughly what before/after mean.
Should distinguish relationship-based before/after from priority-based @AutoConfigureOrder and know the 2.7+ attribute form.
Should tie ordering to conditional back-off semantics and know it only applies to auto-config classes.
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