skip to content

When a slice enables 'only the relevant auto-configuration', where does that curated list physically come from, and how has it changed across Spring Boot versions?

level: seniorimportance: should knowfreq 40%

answer

  1. curated named list, not full scan
  2. spring.factories key (old) → META-INF/spring/<FQN>.imports (new, Boot 2.7/3)
  3. key = @AutoConfigureXxx FQN
  4. imported classes still run @ConditionalOnXxx
  5. custom slice → register in right file

basics

~10 s

Each @AutoConfigureXxx is backed by @ImportAutoConfiguration, which reads a fixed list of auto-config class names from a resource file — historically a key in META-INF/spring.factories, and in modern Boot a META-INF/spring/<annotation>.imports file.

solid answer

~40 s

A slice doesn't do full condition-matching over every auto-config; each `@AutoConfigureXxx` enabler is meta-annotated with `@ImportAutoConfiguration`, which loads a **curated, named list** of auto-configuration classes from a resource. Historically (Boot 1.x–2.x) that list was a property key in `META-INF/spring.factories`, keyed by the annotation's fully-qualified name. From Boot 2.7 and fully in 3.x, auto-configuration registration moved to per-class `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` files, and slice-import lists likewise live in `META-INF/spring/<AnnotationFQN>.imports`. So the slice enables exactly the classes named there — for example `@AutoConfigureDataJpa` maps to Hibernate/JPA/transaction/DataSource auto-configs. This is why slices are deterministic and fast: they import a pre-curated subset instead of evaluating the whole auto-config chain, then let each imported class's `@ConditionalOnXxx` decide activation.

code

java · 16 lines
java
// Modern Boot: AutoConfiguration.imports is a plain text manifest, one class per line.
// File: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
//   com.acme.metrics.CustomMetricsAutoConfiguration
//   # comments allowed

// A slice enabler is just @ImportAutoConfiguration keyed by its own FQN:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ImportAutoConfiguration   // value-less: reads the list from the .imports resource
public @interface AutoConfigureDataJpa {
}

// In a test you can bypass the manifest and name classes explicitly:
@WebMvcTest(OrderController.class)
@ImportAutoConfiguration(CustomMetricsAutoConfiguration.class) // explicit, no file lookup
class OrderControllerTest { /* ... */ }

go deeper

for a junior

Aware that the slice enables a fixed subset of auto-config, not everything.

for a middle

Know @ImportAutoConfiguration reads a curated list keyed by the annotation name.

for a senior

Explain the spring.factories → META-INF/spring/*.imports migration and that imported classes still evaluate their own conditions.

for a principal

Author custom slices/starters registering auto-config in the correct format; reason about version-specific list contents and portability.

## The core idea When we say a slice 'loads only the relevant auto-configuration', it is **not** running Spring Boot's normal `@EnableAutoConfiguration` and letting conditions prune the full set. That's disabled (`@OverrideAutoConfiguration(enabled=false)`). Instead, each `@AutoConfigureXxx` annotation carries `@ImportAutoConfiguration`, which pulls in a **pre-curated, explicitly-named list** of auto-configuration classes. ## Where the list physically lives `@ImportAutoConfiguration` (when used value-less on a meta-annotation) resolves the list of classes to import from a **resource keyed by the annotation's fully-qualified name**: - **Boot 1.x / 2.x**: entries in `META-INF/spring.factories`, e.g. ``` org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa=\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ ... ``` The key is the `@AutoConfigureXxx` annotation's FQN; the value is the comma-separated list of auto-config classes to import. - **Boot 2.7 → 3.x**: Spring Boot introduced a new registration format. General application auto-configuration moved from the `spring.factories` `EnableAutoConfiguration` key to per-module `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` files (one class per line, `#` comments allowed). Correspondingly, the slice import lists are sourced from `META-INF/spring/<AnnotationFQN>.imports` files. So `@AutoConfigureDataJpa`'s list lives in a file named after that annotation's FQN under `META-INF/spring/`. Either way, the crucial point: **the subset is curated and shipped inside the spring-boot-test-autoconfigure jar**, per `@AutoConfigureXxx` annotation. It is a fixed manifest, not a runtime scan. ## How activation still stays conditional Importing a class doesn't force it to create beans. Each imported auto-config still evaluates its own `@ConditionalOnClass`, `@ConditionalOnMissingBean`, `@ConditionalOnBean`, etc. So the slice narrows the *candidate* set to the curated list; conditions then decide what actually activates given the (slim) context and classpath. ## Why the design matters - **Determinism / speed**: importing a known small list avoids evaluating hundreds of auto-config classes. - **Isolation**: unrelated infrastructure (e.g. web server, messaging) is simply never a candidate in a data slice. - **Extensibility**: you add to the candidate set with `@ImportAutoConfiguration(X.class)` or another `@AutoConfigureXxx` — the same mechanism. ## Gotchas / version notes - If you maintain a **custom slice or custom starter**, you must register your auto-config in the correct file for your Boot version (`spring.factories` vs `AutoConfiguration.imports`). Mixing them up means your class is never imported. - The exact contents of these curated lists are Boot-version-specific — never assume a given auto-config is in a slice; inspect the annotation's `@AutoConfigureXxx` stack / the `.imports` files. - `@ImportAutoConfiguration` with an explicit `value` bypasses the file lookup and imports exactly the named classes — handy in tests where you don't want to rely on a manifest. - Boot 3 also generally requires the modern `.imports` format; `spring.factories` `EnableAutoConfiguration` entries are deprecated for auto-config registration.

  • Does importing an auto-config via a slice guarantee its beans are created?
    No. The slice only makes the class a candidate. Each imported auto-configuration still evaluates its own @ConditionalOnClass/@ConditionalOnBean/@ConditionalOnMissingBean, so activation depends on the slim context and classpath.
  • You wrote a custom slice but your auto-config never loads. What's the first thing to check?
    Whether it's registered in the format your Boot version expects — a spring.factories key (older) or a META-INF/spring/<AnnotationFQN>.imports file (Boot 2.7/3.x). A misplaced/misnamed manifest means it's never imported.

saying these in an interview costs you the question

  • Claiming slices run full @EnableAutoConfiguration and just filter results
  • Assuming the list is discovered by classpath scanning rather than a shipped manifest
  • Not knowing spring.factories moved to AutoConfiguration.imports in Boot 2.7/3

context