Auto-Configuration
Auto-configuration is the feature that lets Spring Boot wire up a working application from almost nothing: add spring-boot-starter-web and you get an embedded Tomcat, a DispatcherServlet, JSON serialization, and sensible defaults — without writing a single @Bean. This page explains how that machinery works and how to inspect and override it.
How @EnableAutoConfiguration works
Auto-configuration is triggered by @EnableAutoConfiguration. You rarely write it directly because the meta-annotation @SpringBootApplication already includes it:
@SpringBootApplication // = @Configuration + @ComponentScan + @EnableAutoConfiguration
public class StoreApplication {
public static void main(String[] args) {
SpringApplication.run(StoreApplication.class, args);
}
}
At startup, @EnableAutoConfiguration asks Spring Boot to find every candidate auto-configuration class on the classpath and apply it. Each candidate is itself a @Configuration class guarded by conditional annotations, so it only contributes beans when its conditions match. The result: configuration appears as a side effect of the dependencies (the starters) you put on the classpath.
Where candidates are declared
Spring Boot finds candidates by reading a resource file packaged in every autoconfigure jar:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
This is a plain-text file with one fully-qualified class name per line:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
Note: This
.importsfile is the Spring Boot 2.7+ / 3.x mechanism. It replaced the older approach of listing classes under theorg.springframework.boot.autoconfigure.EnableAutoConfigurationkey insideMETA-INF/spring.factories. In Spring Boot 3.x thespring.factoriesform for auto-configuration has been removed, so any custom auto-config must use the.importsfile.
Each class is annotated with @AutoConfiguration (the 3.x stereotype that specializes @Configuration and supports ordering attributes):
@AutoConfiguration
@ConditionalOnClass(ObjectMapper.class)
public class JacksonAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.build();
}
}
The condition evaluation report
To see exactly which auto-configurations matched and which were rejected, start the app with --debug:
java -jar store.jar --debug
# or with the Maven plugin:
./mvnw spring-boot:run -Dspring-boot.run.arguments=--debug
This prints the condition evaluation report, grouped into positive and negative matches:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required class 'javax.sql.DataSource' (OnClassCondition)
JacksonAutoConfiguration#objectMapper matched:
- @ConditionalOnMissingBean (types: ObjectMapper) did not find any beans (OnBeanCondition)
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class
'jakarta.jms.ConnectionFactory' (OnClassCondition)
MongoAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class
'com.mongodb.client.MongoClient' (OnClassCondition)
Read it as the answer to “why is (or isn’t) this bean here?” A positive match means the class/bean was applied; a negative match lists the specific condition that failed. This is the fastest way to debug missing or unexpected beans.
Tip: Setting
debug=trueinapplication.propertiesproduces the same report. The report is logged once at startup; it does not change which beans are created — it only explains the decisions.
Excluding auto-configurations
Sometimes a starter pulls in an auto-config you do not want. There are two ways to exclude it.
1. The exclude attribute on @SpringBootApplication (or @EnableAutoConfiguration):
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
public class StoreApplication {
public static void main(String[] args) {
SpringApplication.run(StoreApplication.class, args);
}
}
Use excludeName with a string when the class is not on the compile classpath.
2. The spring.autoconfigure.exclude property — handy because it can be set per environment or profile:
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
| Approach | Scope | Best when |
|---|---|---|
exclude attribute | Compile-time, always applied | The class is on the classpath and never wanted |
excludeName attribute | Same, but string-based | The class may be absent at compile time |
spring.autoconfigure.exclude | Per-environment via config | You want to exclude only in some profiles |
Warning: Excluding an auto-configuration like
DataSourceAutoConfigurationwhile a JDBC starter is still on the classpath means you must supply that infrastructure yourself, or related beans (repositories,JdbcTemplate) will fail to wire. Exclude with intent, and confirm the result in the--debugreport.
Override, don’t fight
Because most auto-config beans are guarded by @ConditionalOnMissingBean, the cleanest way to change behavior is usually to define your own bean rather than exclude the whole class. Your bean is registered first, the auto-config’s default backs off, and the rest of the auto-configuration keeps working.
Best Practices
- Let starters drive auto-configuration; add a dependency rather than hand-wiring infrastructure beans.
- Use
--debug(ordebug=true) early when a bean is missing or duplicated — the report names the exact condition. - Prefer overriding a single bean over excluding an entire auto-configuration class.
- When you must exclude, prefer the
@SpringBootApplication(exclude = ...)attribute for permanent removals andspring.autoconfigure.excludefor per-profile removals. - For custom auto-config, register classes via
AutoConfiguration.imports, never the removedspring.factorieskey.