Auto-Configuration
IntermediateSpring Boot scans the classpath and conditionally creates beans on your behalf; understanding @EnableAutoConfiguration and spring.factories unlocks deep customisation.
Overview
Auto-configuration is the cornerstone of Spring Boot's "convention over configuration" philosophy. When you add spring-boot-starter-data-jpa to your project, Spring Boot automatically creates a DataSource, EntityManagerFactory, and TransactionManager — without a single explicit @Bean declaration. This works through @EnableAutoConfiguration (included in @SpringBootApplication), which loads hundreds of configuration classes from META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Spring Boot 3+) or spring.factories (Spring Boot 2.x). Each class is heavily conditional — it only activates when specific classes, beans, or properties are present. Understanding this mechanism lets you write your own starters, override auto-configured beans, and debug unexpected behaviour efficiently.
How Auto-Configuration Works Internally
At startup, ImportAutoConfigurationImportSelector loads all auto-configuration classes from the imports file. Each class is a @Configuration annotated with @Conditional variants. Spring evaluates every condition before deciding whether to register the beans inside. Two rules are critical:
1. Auto-configuration classes are processed after all user-defined beans — your @Bean definitions always win. 2. @ConditionalOnMissingBean skips the auto-configured bean if you have already registered one of that type.
// Spring Boot 3 imports file:
// META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
// Simplified example of DataSourceAutoConfiguration
@AutoConfiguration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class })
protected static class PooledDataSourceConfiguration { }
}Key @Conditional Annotations
@ConditionalOnClass — fires only if the specified class is on the classpath (e.g., DataSource.class). @ConditionalOnMissingBean — skipped if a bean of that type already exists — the primary override mechanism. @ConditionalOnProperty — activates when a property key has a given value (e.g., spring.datasource.url). @ConditionalOnWebApplication — only in a web (Servlet or Reactive) context. @ConditionalOnExpression — complex boolean conditions via Spring EL.
// Override the auto-configured DataSource with your own
@Configuration
public class MyDataSourceConfig {
@Bean // Your bean is registered first => auto-config's @ConditionalOnMissingBean skips it
public DataSource dataSource(DataSourceProperties props) {
return DataSourceBuilder.create()
.url(props.getUrl())
.username(props.getUsername())
.password(props.getPassword())
.driverClassName("com.mysql.cj.jdbc.Driver")
.build();
}
}
// Disable auto-config entirely via application.properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfigurationDebugging Auto-Configuration
Start the application with --debug (or debug=true in application.properties) to print the ConditionEvaluationReport. It lists every auto-configuration class, whether it matched, and the exact condition reason — invaluable when a bean is missing or an unexpected bean appears in the context.
# Run with debug flag
java -jar myapp.jar --debug
# Or set in application.properties
debug=true
# Excerpt from ConditionEvaluationReport output:
# Positive matches:
# DataSourceAutoConfiguration matched:
# - @ConditionalOnClass found required classes 'DataSource' (OnClassCondition)
#
# Negative matches:
# MongoAutoConfiguration:
# Did not match: @ConditionalOnClass did not find required class
# 'com.mongodb.MongoClient' (OnClassCondition)Key Points to Remember
- 1@SpringBootApplication includes @EnableAutoConfiguration which triggers the entire auto-configuration loading mechanism.
- 2Auto-configuration classes are loaded from META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Boot 3) or META-INF/spring.factories (Boot 2).
- 3@ConditionalOnMissingBean is the primary escape hatch — declare your own @Bean of the same type to override any auto-configured bean.
- 4User-defined beans are always registered before auto-configured ones, so explicit definitions always win.
- 5Use the --debug flag to print the ConditionEvaluationReport and understand exactly why each auto-config fired or was skipped.
- 6Write your own Spring Boot starter by creating a @Configuration class with @Conditional annotations and registering it in the AutoConfiguration.imports file.
Interview Questions
Sign in to ask AriaHow does Spring Boot auto-configuration work internally — what loads the configuration classes?
How do you disable a specific auto-configuration class in Spring Boot?
What is the difference between @ConditionalOnClass and @ConditionalOnMissingBean?
How would you create a custom Spring Boot starter with auto-configuration?
What happens when you define your own DataSource @Bean in a Spring Boot app that already has datasource auto-config?
Ask Aria about Auto-Configuration
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.