@ConditionalOnBean and @ConditionalOnMissingBean
Spring Boot conditionally creates configuration or beans depending on whether matching beans are already present in the application context. These annotations are commonly used to make auto-configuration back off when an application provides its own implementation.
`@ConditionalOnBean` matches when one or more specified bean types or names are available in the `ApplicationContext`. A configuration class or bean definition guarded by it is considered only when the required beans can be found.
`@ConditionalOnMissingBean` is the complementary condition: it matches when the specified bean type, name, or annotation is not already present. This is especially useful for defaults, because an application's explicit bean can take precedence over an auto-configured one.
These conditions are evaluated while Spring Boot processes configuration. The result depends on what bean definitions are visible at that point, so ordering between configuration classes can matter. In auto-configuration, this is why conditional configuration should generally be designed with the expected configuration order and bean dependencies in mind.
Both annotations support several matching attributes, including `value`, `type`, `name`, and `annotation` in appropriate forms. `search` can control whether matching considers the current context only or also relevant parent contexts.
A common pattern is to provide a default implementation only when the application has not supplied one: annotate the default bean with `@ConditionalOnMissingBean`. Conversely, `@ConditionalOnBean` can enable a feature only when another required infrastructure bean exists.
Key points
- `@ConditionalOnBean` activates configuration when matching beans exist.
- `@ConditionalOnMissingBean` activates configuration when matching beans do not exist.
- These annotations are central to Spring Boot auto-configuration and its back-off behavior.
- Matching can be based on bean types, names, or annotations, depending on the configured attributes.
- Condition evaluation can depend on configuration processing order and the beans visible at that point.
Interview questions
What is the purpose of `@ConditionalOnMissingBean` in Spring Boot?
It lets Spring Boot provide a default bean only when the application has not already defined a matching bean. This is a common auto-configuration pattern. If the application supplies its own implementation, the conditional configuration backs off. That allows application-specific configuration to override framework defaults.
How does `@ConditionalOnBean` differ from `@ConditionalOnMissingBean`?
`@ConditionalOnBean` matches when the requested bean is available, while `@ConditionalOnMissingBean` matches when it is not. The former is useful for enabling configuration that requires existing infrastructure. The latter is useful for supplying optional defaults. Together they let auto-configuration adapt to what the application has already configured.
Why can configuration ordering matter when using `@ConditionalOnMissingBean`?
The condition is evaluated while Spring Boot is processing configuration, not after every possible bean has necessarily been instantiated. If a configuration that defines a candidate bean has not been processed yet, a missing-bean condition may initially appear to match. Spring Boot therefore provides ordering mechanisms for auto-configuration and recommends designing conditions with configuration ordering in mind. This is particularly important when one auto-configuration depends on another.
What can `@ConditionalOnBean` match against?
It can be configured to match bean types, bean names, or annotations, depending on the attributes used. For example, `@ConditionalOnBean(MyService.class)` expresses a type-based requirement. The annotation also has options affecting where the search is performed, such as the current application context versus relevant ancestors. The exact matching criteria should therefore be chosen to reflect the dependency the configuration actually requires.
How would you design an auto-configuration that provides a default implementation but allows users to override it?
I would define the default implementation in an auto-configuration class and guard it with `@ConditionalOnMissingBean` for the extension point's type. The application can then define its own bean of that type, causing the default configuration to be skipped. If the default also requires another infrastructure bean, I could combine the missing-bean condition with `@ConditionalOnBean`. I would also consider auto-configuration ordering so the condition evaluates against the intended set of candidate beans.