Spring Boot Auto-Configuration
Overview
Auto-configuration is one of Spring Boot's most powerful features. It automatically configures your Spring application based on the dependencies present on the classpath, reducing the need for manual configuration.
How Auto-Configuration Works
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies you have added. For example, if
spring-boot-starter-data-jpaDataSourceEntityManagerFactoryTransactionManagerKey Components
- @EnableAutoConfiguration: Enables auto-configuration mechanism
- @Conditional Annotations: Control when configurations are applied
- spring.factories: Lists all auto-configuration classes
- Auto-Configuration Classes: Pre-built configuration classes
@EnableAutoConfiguration
The
@EnableAutoConfigurationimport org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
public class MyConfiguration {
// Configuration code
}Note:
already includestext@SpringBootApplication, so you typically don't need to add it explicitly.text@EnableAutoConfiguration
Conditional Auto-Configuration
Auto-configuration classes use
@ConditionalCommon @Conditional Annotations
| Annotation | Description |
|---|---|
text | Configuration only loaded if specified class is present |
text | Configuration loaded if specified class is NOT present |
text | Configuration loaded if specified bean exists |
text | Configuration loaded if specified bean does NOT exist |
text | Configuration loaded based on Spring property |
text | Configuration loaded if specified resource exists |
text | Configuration loaded if it's a web application |
text | Configuration loaded if it's NOT a web application |
Example: Custom Auto-Configuration
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnProperty(name = "myapp.service.enabled", havingValue = "true", matchIfMissing = true)
public class MyServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new MyServiceImpl();
}
@Bean
@ConditionalOnBean(DataSource.class)
public MyDataService myDataService(DataSource dataSource) {
return new MyDataService(dataSource);
}
}Viewing Auto-Configuration Report
You can view which auto-configurations were applied by enabling debug logging:
Method 1: application.properties
debug=trueMethod 2: Command Line
java -jar myapp.jar --debugMethod 3: IDE
mvn spring-boot:run -DdebugThe report shows:
- Positive matches: Auto-configurations that were applied
- Negative matches: Auto-configurations that were not applied (and why)
- Exclusions: Auto-configurations explicitly excluded
- Unconditional classes: Auto-configurations with no conditions
Creating Custom Auto-Configuration
Step 1: Create Auto-Configuration Class
package com.example.autoconfigure;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
@ConditionalOnClass(MyLibraryClass.class)
@EnableConfigurationProperties(MyLibraryProperties.class)
public class MyLibraryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyLibraryService myLibraryService(MyLibraryProperties properties) {
return new MyLibraryService(properties.getApiKey());
}
}Step 2: Create Configuration Properties
package com.example.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "mylibrary")
public class MyLibraryProperties {
private String apiKey;
private boolean enabled = true;
private int timeout = 5000;
// Getters and setters
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
}Step 3: Register Auto-Configuration
Create
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importscom.example.autoconfigure.MyLibraryAutoConfigurationNote: For Spring Boot 2.x, use
instead:textMETA-INF/spring.factoriespropertiesorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.autoconfigure.MyLibraryAutoConfiguration
Excluding Auto-Configuration
Sometimes you need to disable certain auto-configurations.
Method 1: Using @SpringBootApplication
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}Method 2: Using application.properties
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurationMethod 3: Using @EnableAutoConfiguration
@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class MyConfiguration {
}Common Auto-Configurations
Web Auto-Configuration
// Automatically configured when spring-boot-starter-web is present
- DispatcherServlet
- Embedded Tomcat
- Jackson (JSON processing)
- Error handlingData Auto-Configuration
// Automatically configured when spring-boot-starter-data-jpa is present
- DataSource
- EntityManagerFactory
- TransactionManager
- JPA repositoriesSecurity Auto-Configuration
// Automatically configured when spring-boot-starter-security is present
- Default security configuration
- Basic authentication
- CSRF protection
- Security filter chainAuto-Configuration Ordering
You can control the order in which auto-configurations are applied:
@AutoConfiguration
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@AutoConfigureAfter(MyOtherAutoConfiguration.class)
public class MyAutoConfiguration {
// Configuration
}Ordering Annotations
| Annotation | Purpose |
|---|---|
text | Run this configuration before specified classes |
text | Run this configuration after specified classes |
text | Specify numeric order (lower values = higher priority) |
Best Practices
1. Use @ConditionalOnMissingBean for Default Beans
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new DefaultMyService();
}This allows users to provide their own implementation by defining a bean.
2. Provide Configuration Properties
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private boolean enabled = true;
private String apiUrl;
// getters and setters
}3. Use Specific @Conditional Annotations
@Bean
@ConditionalOnClass(name = "javax.sql.DataSource")
@ConditionalOnProperty(name = "spring.datasource.url")
public DataSource dataSource() {
// Configure DataSource
}4. Document Your Auto-Configuration
Create
META-INF/spring-configuration-metadata.json{
"properties": [
{
"name": "myapp.enabled",
"type": "java.lang.Boolean",
"description": "Enable MyApp features",
"defaultValue": true
},
{
"name": "myapp.api-url",
"type": "java.lang.String",
"description": "API endpoint URL"
}
]
}5. Test Your Auto-Configuration
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.junit.jupiter.api.Test;
class MyAutoConfigurationTest {
private final ApplicationContextRunner contextRunner =
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class));
@Test
void testAutoConfiguration() {
contextRunner.run(context -> {
assertThat(context).hasSingleBean(MyService.class);
});
}
@Test
void testWhenDisabled() {
contextRunner
.withPropertyValues("myapp.enabled=false")
.run(context -> {
assertThat(context).doesNotHaveBean(MyService.class);
});
}
}Troubleshooting
Issue: Configuration Not Applied
Solution: Check conditions with debug mode:
debug=true
logging.level.org.springframework.boot.autoconfigure=DEBUGIssue: Wrong Bean Selected
Solution: Use
@Primary@Qualifier@Bean
@Primary
public MyService primaryMyService() {
return new PrimaryMyServiceImpl();
}Issue: Circular Dependencies
Solution: Use
@Lazy@Bean
@Lazy
public MyService myService(OtherService otherService) {
return new MyServiceImpl(otherService);
}Summary
- Auto-configuration automatically sets up your application based on classpath dependencies
- Uses annotations to determine when to apply configurationstext
@Conditional - Can be customized, excluded, or overridden as needed
- Enable debug mode to see which auto-configurations are applied
- Create custom auto-configurations for reusable library configuration
- Always provide default values and make configurations optional when possible
Next Steps
- Learn about Configuration Management
- Explore Spring Boot Starters
- Study Profiles Advanced