@ConditionalOnClass and @ConditionalOnMissingClass

Spring Boot uses `@ConditionalOnClass` and `@ConditionalOnMissingClass` to activate configuration only when specified classes are present or absent from the application classpath. They are commonly used to make auto-configuration adapt to optional dependencies.

`@ConditionalOnClass` matches when all specified classes can be found on the classpath. This lets an auto-configuration module provide beans only when the library those beans depend on is actually available.

`@ConditionalOnMissingClass` is the inverse-style condition: it matches when the named classes cannot be found. It is useful when configuration should apply only when an optional library is not installed, such as selecting a fallback implementation.

Both annotations are part of Spring Boot's conditional configuration mechanism. They are most often encountered in auto-configuration, where several configurations may coexist and each decides whether it should contribute beans.

Class names can be supplied through annotation attributes such as `value` or `name`. Using `name` is useful when referring to an optional class without requiring that class to be loadable by the configuration class itself.

A subtle point is that class-level conditions are generally safer for optional dependencies than putting a condition directly on a `@Bean` method whose return type references an optional class. JVM class loading can happen before Spring gets an opportunity to evaluate the condition, so optional-type references are commonly isolated behind a nested or separate configuration class.

Key points

Interview questions

Why might a class-level `@ConditionalOnClass` be preferable when the optional class is used by a `@Bean` method?

The condition is intended to prevent configuration from being processed when an optional dependency is unavailable. However, referring directly to an optional type in a configuration class or method signature can cause that type to be loaded before Spring Boot evaluates the condition. A common design is to isolate the optional type behind a configuration class that is guarded by the class condition. This keeps JVM class loading from defeating the intended optionality.

What is the purpose of `@ConditionalOnClass` in Spring Boot?

`@ConditionalOnClass` allows Spring Boot configuration to activate only when specified classes are available on the application's classpath. This is especially useful for auto-configuration with optional libraries. It prevents configuration from being applied when its required integration library is not installed. The condition is about class availability, not whether a Spring bean of that class exists.

How does `@ConditionalOnMissingClass` differ from `@ConditionalOnClass`?

`@ConditionalOnClass` matches when the specified classes are available. `@ConditionalOnMissingClass` matches when the specified classes are unavailable. They can therefore support alternative configuration paths based on whether an optional library is installed. Neither annotation checks whether a Spring bean has been registered.

What is the difference between `@ConditionalOnMissingClass` and `@ConditionalOnMissingBean`?

`@ConditionalOnMissingClass` asks whether particular classes are absent from the classpath. `@ConditionalOnMissingBean` asks whether particular beans are absent from the Spring application context. A library can therefore be present without a corresponding bean being registered. Choosing between them depends on whether the configuration decision is based on dependency availability or on the application's existing bean configuration.

How would you design auto-configuration for an optional third-party client library?

I would first guard the integration configuration with `@ConditionalOnClass` for the client types it requires. I would isolate references to optional types so they are not loaded before the condition is evaluated. I would then consider additional conditions such as `@ConditionalOnMissingBean` so user-defined beans can take precedence over defaults. If there is a fallback implementation, I could use `@ConditionalOnMissingClass` or another appropriate condition for that path.