Skip to main content
Spring Framework · Topic 8 of 25

Auto-Configuration

Definition​

Auto-configuration is Boot creating beans for you automatically when certain conditions are met, such as a library being on the classpath. If you define your own bean, the automatic one steps aside.

Why it exists​

Setting up a data source, JSON mapper and web server is the same boilerplate in every project. Auto-configuration does the common setup and still lets you override any part.

How it works​

The mechanism​

  1. @EnableAutoConfiguration (inside @SpringBootApplication) imports an AutoConfigurationImportSelector.
  2. The selector reads the file META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports from every JAR on the classpath. Each line is a configuration class name. (Older Boot versions used spring.factories for this.)
  3. Each candidate class is evaluated. Its @Conditional... annotations decide whether it contributes beans.
  4. Auto-configuration is processed after your own configuration, which is why your beans win.

Common conditions​

AnnotationApplies when
@ConditionalOnClass / @ConditionalOnMissingClassA class is (not) on the classpath
@ConditionalOnBean / @ConditionalOnMissingBeanA bean of that type is (not) already defined
@ConditionalOnPropertyA property has a given value
@ConditionalOnWebApplicationServlet or reactive web app
@ConditionalOnResourceA file exists

Example code​

Overriding and excluding​

Define your own bean and the default backs off:

@Configuration
class JsonConfig {

@Bean
ObjectMapper objectMapper() {
// JacksonAutoConfiguration's mapper is @ConditionalOnMissingBean, so this wins.
return new ObjectMapper().findAndRegisterModules();
}
}

Be careful: replacing the mapper this way drops Boot's defaults (for example spring.jackson.* properties). Often a Jackson2ObjectMapperBuilderCustomizer bean is the better tool.

To turn a configuration off entirely:

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class App { }

or spring.autoconfigure.exclude=... in properties.

Writing your own auto-configuration​

This is how starters for your company's shared libraries work. A tiny example: a GreetingService that is created unless the application provides one, and can be switched off by property.

public class GreetingService {
private final String greeting;

public GreetingService(String greeting) {
this.greeting = greeting;
}

public String greet(String name) {
return greeting + ", " + name + "!";
}
}
@ConfigurationProperties(prefix = "greeting")
public class GreetingProperties {
private String message = "Hello";

public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}
@AutoConfiguration
@EnableConfigurationProperties(GreetingProperties.class)
@ConditionalOnProperty(prefix = "greeting", name = "enabled", matchIfMissing = true)
public class GreetingAutoConfiguration {

@Bean
@ConditionalOnMissingBean
GreetingService greetingService(GreetingProperties props) {
return new GreetingService(props.getMessage());
}
}

Register it in src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:

com.example.greeting.GreetingAutoConfiguration

Note that auto-configuration classes must not be found by component scanning of the consuming app; that is why they are listed in the imports file instead of being annotated with @Component.

System design considerations​

  • Run the application with the conditions report when upgrading Boot or dependencies
  • Test custom auto-configuration with ApplicationContextRunner
  • Namespace your properties and document defaults

Seeing what Boot decided​

Start the app with --debug (or debug=true). The conditions evaluation report lists:

  • Positive matches: configurations that were applied and why.
  • Negative matches: configurations skipped and which condition failed.
  • Exclusions and Unconditional classes.

The Actuator conditions endpoint exposes the same data on a running app.

When to use it, and when not​

Use it when

  • You want sensible defaults and override only what differs
  • You build a shared starter for several teams
  • You diagnose why a bean exists or does not

Think twice when

  • You depend on a specific bean being configured but never verified the condition
  • You exclude auto-configurations broadly without understanding what they provide
  • Behaviour changes silently after a dependency upgrade

Common mistakes​

  • Using @ConditionalOnBean in application configuration, where bean registration order is unpredictable.
  • Overriding a bean by name or type and unintentionally losing property-driven customisation.
  • Component-scanning an auto-configuration package, which bypasses the conditions.
  • Forgetting the imports file after renaming a class; the configuration silently stops applying.

Interview questions​

1. How does Spring Boot auto-configuration work?

@EnableAutoConfiguration loads candidate configuration class names from AutoConfiguration.imports files on the classpath. Each class is guarded by conditions; those that pass register beans. Since they are processed after user configuration and mostly use @ConditionalOnMissingBean, user-defined beans take precedence.

2. How do you find out why a bean was or was not created?

Run with --debug or call the Actuator /actuator/conditions endpoint. Negative matches show the failed condition.

3. How would you disable one auto-configuration?

exclude on @SpringBootApplication / @EnableAutoConfiguration, or the spring.autoconfigure.exclude property.

4. How do you create a custom starter?

Two modules by convention: an -autoconfigure module holding the @AutoConfiguration class, properties and the imports file, and a thin -starter module that depends on it plus the needed libraries. Name it acme-spring-boot-starter, not spring-boot-starter-acme (that prefix is reserved for the Boot team).

5. What is the difference between @ConditionalOnBean and @ConditionalOnMissingBean in terms of ordering?

Both depend on what has been registered so far, so they are only reliable in auto-configuration classes ordered with @AutoConfiguration(after = ...). In ordinary user configuration, ordering is not guaranteed and these conditions can behave unexpectedly.

Check yourself​

Quick quiz3 questions

1How does Boot decide to create a DataSource automatically?

2Which flag shows which auto-configurations matched or not?

3You define your own DataSource bean. What happens to the auto-configured one?

Key takeaways​

  • Auto-configuration = conditional @Configuration classes listed in AutoConfiguration.imports.
  • It runs after user configuration and backs off via @ConditionalOnMissingBean.
  • Debug with --debug or /actuator/conditions.
  • Custom starters are an autoconfigure module plus a thin starter module.

Next: Starters and dependency management.

Next topicConfiguration and properties

Finished this page? Track your progress (saved only in your browser).