@Conditional and its variants: @ConditionalOnClass, @Cond… — Cracked Java
// Spring Framework & Spring Boot · Spring Boot Auto-Configuration
SeniorTheoryCoding

@Conditional and its variants: @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty, @ConditionalOnWebApplication.

@Conditional is the foundation of everything in auto-configuration: it registers a bean or configuration class only when a supplied Condition returns true. Boot ships a family of ready-made conditions so you almost never implement the raw Condition interface yourself.

The base mechanism

public class OnLinuxCondition implements Condition {
    public boolean matches(ConditionContext ctx, AnnotatedTypeMetadata md) {
        return ctx.getEnvironment().getProperty("os.name", "").contains("Linux");
    }
}

@Bean
@Conditional(OnLinuxCondition.class)
DaemonManager daemonManager() { ... }

Boot's variants are all specializations of this, evaluated at context-startup time.

@ConditionalOnClass / @ConditionalOnMissingClass

Match on classpath presence. This is the mechanism behind "add the jar, get the beans." It uses class names via ASM so it works even when the type isn't loadable:

@ConditionalOnClass(name = "com.zaxxer.hikari.HikariDataSource")

@ConditionalOnMissingBean / @ConditionalOnBean

@ConditionalOnMissingBean is why your @Bean always wins — Boot only contributes a default if you haven't defined one:

@Bean
@ConditionalOnMissingBean        // back off if the user defined an ObjectMapper
ObjectMapper objectMapper() { return new ObjectMapper(); }

These are ordering-sensitive: they see beans defined so far, which is why auto-config runs after user config and why @AutoConfiguration ordering matters.

@ConditionalOnProperty

Gate on a property's presence/value — the standard feature flag:

@Bean
@ConditionalOnProperty(prefix = "acme.cache", name = "enabled",
                       havingValue = "true", matchIfMissing = false)
CacheManager cacheManager() { ... }

matchIfMissing = true makes the feature on-by-default.

@ConditionalOnWebApplication / @ConditionalOnNotWebApplication

Match only in a web context, optionally narrowed to servlet or reactive:

@ConditionalOnWebApplication(type = Type.SERVLET)

Other common variants

  • @ConditionalOnResource — a resource exists (classpath:schema.sql).
  • @ConditionalOnExpression — an arbitrary SpEL expression.
  • @ConditionalOnSingleCandidate — exactly one candidate bean of a type exists.
  • @ConditionalOnJava — a JVM version range.

Mark your status