How Auto-Configuration Reacts to Dependencies
Understand @EnableAutoConfiguration, @ConditionalOnClass and @ConditionalOnMissingBean, and how to see exactly which auto-configurations are active in your application.
Introduction
By now you know that adding a dependency like a JDBC driver "just works" once it is on the classpath — Spring Boot notices it and configures the relevant beans automatically. This lesson explains exactly how that happens under the hood, using conditional annotations that check what is (and is not) present.
@EnableAutoConfiguration
The `@SpringBootApplication` annotation you put on your main class bundles together `@EnableAutoConfiguration`, which is the switch that turns this whole mechanism on. When your application starts, Spring Boot scans a list of auto-configuration classes (registered via a file inside spring-boot-autoconfigure.jar) and evaluates each one to decide whether it should activate.
@SpringBootApplication // includes @EnableAutoConfigurationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}Conditional Annotations
Each auto-configuration class is guarded by one or more conditional annotations that check the state of your project before deciding to activate. The two you will see constantly are `@ConditionalOnClass` (activate only if a given class is on the classpath) and `@ConditionalOnMissingBean` (activate only if you have not already defined your own bean of that type).
@Configuration@ConditionalOnClass(DataSource.class)public class DataSourceAutoConfiguration {
@Bean @ConditionalOnMissingBean public DataSource dataSource(DataSourceProperties properties) { return properties.initializeDataSourceBuilder().build(); }}Read this class as a sentence: "If the `DataSource` class is on the classpath (meaning some JDBC-related dependency is present), configure a `DataSource` bean — but only if the developer has not already defined their own." This is exactly how your own `@Bean` definitions always take priority over Spring Boot's defaults.
Worked Example: DataSourceAutoConfiguration
Consider what happens when you add the H2 in-memory database driver to a project that already has `spring-boot-starter-data-jpa`.
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope></dependency>Click Run to see what this code prints.
You never wrote a single line of `DataSource` configuration — adding one dependency (the H2 driver) alongside an existing starter was enough for two separate auto-configuration classes to chain together and produce a fully working, connected JPA setup.
Seeing Active Auto-Configurations
This can feel like a black box until you know how to inspect it. Spring Boot can print a full "condition evaluation report" showing every auto-configuration class it considered, whether it matched, and exactly why (or why not).
java -jar demo.jar --debugClick Run to see what this code prints.
Alternatively, adding `debug=true` to `application.properties` produces the same report without changing how you launch the JAR. This report is the single best debugging tool when a bean you expect "should just work" is not being created — it tells you exactly which condition failed.
Common Mistakes
- Treating auto-configuration as unpredictable magic instead of reading the condition evaluation report when something does not activate as expected.
- Defining a bean with a slightly different type or name and being surprised @ConditionalOnMissingBean did not detect it — the condition checks the bean's type, so subtle mismatches matter.
- Forgetting that removing a dependency can silently deactivate auto-configuration that other code was relying on.
Best Practices
- Run with `--debug` at least once per project so you understand what is actually being auto-configured.
- When you need to override a default, define your own `@Bean` of the matching type rather than fighting the auto-configuration.
- Use `@ConditionalOnProperty` in your own configuration classes to build feature flags the same way Spring Boot itself does internally.
Frequently Asked Questions
Auto-configuration classes are processed with lower priority than your own configuration, and @ConditionalOnMissingBean specifically checks for your beans first, so your explicit beans always win.
Yes, using @SpringBootApplication(exclude = { SomeAutoConfiguration.class }) or the spring.autoconfigure.exclude property.
Inside the spring-boot-autoconfigure JAR, registered in a META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file (in modern Spring Boot versions).
Key Takeaways
- @EnableAutoConfiguration (bundled into @SpringBootApplication) turns on classpath-driven configuration.
- @ConditionalOnClass activates configuration based on what dependency is present; @ConditionalOnMissingBean lets your own beans always take priority.
- The --debug flag (or debug=true property) prints a full condition evaluation report explaining every decision.
Summary
Auto-configuration is not magic — it is a systematic set of conditional checks against your classpath and your own bean definitions. Understanding this mechanism is what turns "it just works" into "I know exactly why it works." From here, the course moves into the actual dependency catalog, starting with web and REST API dependencies.