Spring Boot Auto-Configuration: Missing HikariCP, No Error
A transitive dependency removed HikariCP; auto-config silently skipped DataSource, causing NPE.
- Auto-Configuration is conditional bean wiring — Spring Boot loads config classes from JAR dependencies but only executes them if classpath and property conditions are met
- @EnableAutoConfiguration triggers a scan of META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (or spring.factories in older versions) across all JARs
- @ConditionalOnClass activates config only when a specific class exists on the classpath — this is how starters adapt to your dependencies
- @ConditionalOnMissingBean provides a default 'opinion' but steps aside when you define your own bean — this is the override mechanism
- The Conditions Evaluation Report (debug=true) shows every positive and negative match with the exact reason each config was accepted or rejected
- The biggest mistake: defining a bean that conflicts with auto-config without understanding @ConditionalOnMissingBean should have skipped the default
Imagine you buy a high-end smart home kit. In the old days — Standard Spring — you had to manually wire the doorbell to the speaker, the lights to the switch, and the thermostat to the heater using a thick manual nobody wanted to read. With Spring Boot Auto-Configuration, the system is smart in the way a good contractor is smart: it walks into the room, sees what is already there, and makes sensible connections without asking you to approve each wire.
It looks around and says: 'I see a lightbulb and a switch — I will connect them.' If you have already installed your own professional dimmer switch — a custom bean — the system notices and steps back: 'You have this covered, I will leave yours in place.' That is not magic. That is conditional logic that respects your decisions. Understanding this distinction is what separates engineers who fight Spring Boot from engineers who ship with it.
Auto-Configuration is the mechanism that allows Spring Boot to achieve its 'just run it' experience. While critics call it magic, it is a predictable sequence of conditional logic gates that evaluate your classpath, your existing beans, and your application properties at startup — in that order.
Misunderstanding auto-configuration causes real production failures. A missing classpath dependency silently skips a critical config class and you find out at 2 AM when every database call is throwing NullPointerException. A conflicting user-defined bean triggers NoUniqueBeanDefinitionException in an environment you cannot reproduce locally. A slow startup caused by evaluating hundreds of unnecessary conditions costs 30 seconds per deployment multiplied across 50 Kubernetes replicas — time nobody budgeted for.
I have debugged all three of these. What they share is that the information was available the whole time in the Conditions Evaluation Report. The engineers involved just did not know to look there.
This guide deconstructs the spring-boot-autoconfigure module to show exactly how the framework manages bean creation using the @Conditional ecosystem. By the end, you will understand how to write your own auto-configurations, read the Conditions Report without panic, and debug missing bean issues without guessing.
The Mechanics of Auto-Configuration: Classpath Discovery
When you annotate your main class with @SpringBootApplication, you are implicitly enabling @EnableAutoConfiguration. This triggers a search for a file named META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports in Spring Boot 3.x, or META-INF/spring.factories in Spring Boot 2.x, across every JAR on your classpath.
Inside these files is a flat list of fully qualified configuration class names. Spring Boot attempts to load all of them. Here is where the conditional logic takes over: every class in that list is annotated with one or more @Conditional annotations that are evaluated before any @Bean method is executed. A configuration class only runs its @Bean methods if every condition on the class passes. If a single condition fails — classpath missing a class, property not set, required bean absent — the entire configuration class is skipped. Silently.
This is the mechanism that makes a single spring-boot-starter-data-jpa dependency configure DataSource, EntityManagerFactory, TransactionManager, and Hibernate dialect without you writing a line of configuration XML. It is also the mechanism that silently does nothing when HikariCP disappears from your resolved classpath due to a dependency conflict.
- @ConditionalOnClass checks if a specific class exists on the classpath — evaluated before the Spring context is fully initialized, making it the cheapest condition to evaluate
- @ConditionalOnMissingBean checks if you already defined a bean of that type — your bean wins unconditionally, the auto-configured default steps aside without complaint
- @ConditionalOnProperty checks if a property is set to a specific value — enables runtime toggling between implementations without code changes
- @ConditionalOnBean is the inverse of @ConditionalOnMissingBean — config only activates if a specific prerequisite bean already exists in the context
- @ConditionalOnWebApplication skips configuration entirely for non-web contexts like batch jobs or CLI runners — prevents web-only beans from polluting a non-web context
- Multiple @Conditional annotations on the same class compose with AND logic — every condition must pass, and evaluation stops at the first failure
Debugging the Magic: The Conditions Evaluation Report
The biggest source of frustration with auto-configuration is not that it fails — it is that it fails silently. A condition evaluates to false, the config class is skipped, and Spring Boot moves on without logging anything at INFO level. You are left with a missing bean and no obvious explanation.
The Conditions Evaluation Report fixes this. Add debug=true to application.properties and restart. Spring Boot will print every auto-configuration class it evaluated, categorized into Positive Matches (ran and created beans), Negative Matches (skipped and why), and Unconditional Classes (always run regardless of conditions). Each entry in Negative Matches shows the exact @Conditional annotation that failed and the value it tested against.
This report is also available at runtime without a restart via the Actuator /actuator/conditions endpoint. The JSON format is parseable, diffable between deployments, and can be integrated into your CI pipeline to detect configuration drift.
I treat the Conditions Report as the first tool, not the last resort. When a bean is missing, I check the report before I check the code.
The Missing DataSource — Silent Auto-Configuration Skip
- Auto-Configuration silently skips classes when @ConditionalOnClass fails — no error, no warning, no log line at any level. The absence is the only signal.
- Always check the Conditions Evaluation Report with debug=true when a bean you expect is not present. The negative matches section shows exactly which condition failed and what value was evaluated.
- Never rely on transitive dependency resolution for runtime-critical libraries like HikariCP, Jackson, or Hibernate. Declare them explicitly with a pinned version in your build file.
- Add startup assertions for critical infrastructure beans.
ApplicationContext.getBean()inside an ApplicationRunner throws a meaningful error at boot time instead of a cryptic NullPointerException under production load. - Make the Conditions Evaluation Report part of your incident runbook. A five-second grep against startup logs resolves in minutes what otherwise takes hours.
Key takeaways
Common mistakes to avoid
5 patternsDefining a bean that conflicts with auto-config without understanding @ConditionalOnMissingBean
Forgetting to register custom auto-configuration in the imports file
Over-reliance on auto-configuration without auditing what is being evaluated at startup
Assuming auto-configuration always creates the bean you expect without verifying
Not understanding that @ConditionalOnClass silently skips configuration when the class is missing from the classpath
Interview Questions on This Topic
Explain the internal working of @SpringBootApplication. Which three annotations does it consolidate and what does each one actually do?
Frequently Asked Questions
That's Spring Boot. Mark it forged?
3 min read · try the examples if you haven't