Spring Boot Internals: How Auto-Configuration Really Works
Deep dive into @SpringBootApplication, @Conditional annotations, and the spring.factories mechanism. Understand what happens before your main() even runs.
Spring Boot Internals: How Auto-Configuration Really Works
Overview
Spring Boot's auto-configuration is one of its most powerful features. Understanding how it works under the hood is critical for senior developers who need to debug startup issues, write custom starters, or optimize boot time.
The @SpringBootApplication Annotation
@SpringBootApplication is a meta-annotation that combines three annotations:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication { ... }- @SpringBootConfiguration: Marks the class as a configuration class (extends @Configuration)
- @EnableAutoConfiguration: Triggers the auto-configuration mechanism
- @ComponentScan: Scans the package and sub-packages for components
How EnableAutoConfiguration Works
The @EnableAutoConfiguration annotation imports AutoConfigurationImportSelector, which reads META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Spring Boot 3.x) or META-INF/spring.factories (Spring Boot 2.x).
// AutoConfigurationImportSelector.java (simplified)
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
.getCandidates();
return configurations;
}@Conditional Annotations
Auto-configuration classes use @Conditional variants to conditionally apply configuration:
| Annotation | Condition |
|---|---|
| @ConditionalOnClass | Class is on the classpath |
| @ConditionalOnMissingBean | No bean of that type exists |
| @ConditionalOnProperty | A property is set |
| @ConditionalOnWebApplication | Running in a web context |
@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
public class DataSourceAutoConfiguration {
@Bean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}Interview Questions
- 1.What is the difference between @Configuration and @SpringBootConfiguration?
- 2.How would you exclude a specific auto-configuration class?
- 3.What happens when two auto-configurations define a bean of the same type?
- 4.How do you write a custom Spring Boot starter?
- 5.What is the order of bean initialization in Spring Boot?
Common Pitfalls
- Circular dependencies: Auto-configured beans can create circular dependency issues. Use
@Lazyor restructure. - Ordering issues: Use
@AutoConfigureBefore/@AutoConfigureAfterto control ordering. - Classpath pollution: Adding a dependency can trigger unexpected auto-configurations.