Knowing how Boot decides what to configure lets you override defaults confidently and debug startup.
Auto-configuration is ordinary Spring configuration that Boot applies conditionally. Each auto-configuration class is listed in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports inside the Boot jars (and in third-party starters). At startup Boot loads the list and evaluates each class's conditions:
@ConditionalOnClass(DataSource.class): only if a class is on the classpath. This is why adding a starter "turns on" a feature.@ConditionalOnMissingBean: only if you haven't defined your own bean of that type. This is the back-off rule that lets your configuration win.@ConditionalOnProperty(prefix = "app.cache", name = "enabled", havingValue = "true"): driven by configuration.@ConditionalOnWebApplication,@ConditionalOnBean,@ConditionalOnResourceand more.
Auto-configurations are processed after your own configuration, so the conditions see your beans. Ordering between them uses @AutoConfiguration(after = ...).
To customise, you rarely replace beans; first look for properties (spring.jackson.*) or customizer beans (Jackson2ObjectMapperBuilderCustomizer, WebServerFactoryCustomizer). Defining your own ObjectMapper or DataSource bean makes Boot's back off entirely. Exclude an auto-configuration with @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) or spring.autoconfigure.exclude.
Debug with --debug (or debug=true): the conditions evaluation report lists positive and negative matches with reasons. The /actuator/conditions endpoint shows the same at runtime.
Example
// A simplified version of what Boot ships, showing the patterns
@AutoConfiguration
@ConditionalOnClass(ObjectMapper.class)
public class SimpleJacksonAutoConfiguration {
@Bean
@ConditionalOnMissingBean // backs off if you define one
ObjectMapper objectMapper(ObjectProvider<MapperCustomizer> customizers) {
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
customizers.orderedStream().forEach(c -> c.customize(mapper));
return mapper;
}
}
interface MapperCustomizer { void customize(ObjectMapper mapper); }
// Your app: tweak instead of replace
@Bean
MapperCustomizer indent() {
return m -> m.enable(SerializationFeature.INDENT_OUTPUT);
}
// java -jar app.jar --debug
// Positive matches: SimpleJacksonAutoConfiguration matched: @ConditionalOnClass found ObjectMapper
// Negative matches: DataSourceAutoConfiguration: did not find required class
// 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'Remember
- Auto-configurations are conditional
@Configurationclasses listed inAutoConfiguration.imports @ConditionalOnClassreacts to the classpath;@ConditionalOnMissingBeanlets your beans win- Prefer properties and customizer beans over replacing auto-configured beans
--debugprints the conditions evaluation report
Watch out for
- Defining your own ObjectMapper bean to change one setting and losing all of Boot's Jackson configuration.