Mastering Spring Boot @Conditional Annotations: A Complete Guide
This article explains how Spring Boot's @Conditional annotations—covering class, bean, property, resource, web application, and SpEL expression conditions—can be used to conditionally load configuration and beans, with examples and guidance on custom conditions.
Environment: SpringBoot 2.7.16
1. Introduction
Spring Boot provides many @Conditional annotations that can be applied to @Configuration classes or individual @Bean methods to control their inclusion. The main types are:
Class Conditions
Bean Conditions
Property Conditions
Resource Conditions
Web Application Conditions
SpEL Expression Conditions
2. Class Conditions
@ConditionalOnClass and @ConditionalOnMissingClass allow a configuration class to be included only when a specific class is present or absent.
<code>@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(CustomLogImpl.class)
public class PackConfiguration {
@Bean
public LogAspect logAspect() {
// ...
}
}</code>If you use @ConditionalOnClass or @ConditionalOnMissingClass as part of a meta‑annotation, you must use the name attribute because the class reference will not be processed.
3. Bean Conditions
@ConditionalOnBean and @ConditionalOnMissingBean include a bean based on the presence or absence of another bean. You can specify the bean by type ( value ) or by name ( name ), and the search attribute controls the context hierarchy considered.
<code>@Configuration
public class PackConfiguration {
// Only search in the current container; parent containers are ignored
@Bean
@ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
public UserService userService() {
return new UserService();
}
}</code>Be careful with the order of bean definitions, as conditions are evaluated based on already processed beans.
Note: @ConditionalOnBean and @ConditionalOnMissingBean do not prevent the creation of the @Configuration class itself. The only difference between applying the condition at the class level versus on each @Bean method is that a mismatched class‑level condition stops the configuration class from being registered as a bean.
4. Property Conditions
@ConditionalOnProperty activates a bean when a specific Spring environment property matches. By default, any existing property that is not false matches. You can refine the check with havingValue and matchIfMissing .
<code>@Configuration
public class PropertyCondition {
@Bean
@ConditionalOnProperty(prefix = "pack.config", name = "enabled", havingValue = "true", matchIfMissing = true)
public AnimalService animalService() {
return new AnimalService();
}
}</code>If pack.config.enabled=true is set in the configuration file, or the property is missing, the condition evaluates to true.
5. Resource Conditions
@ConditionalOnResource includes a bean only when a given resource exists on the classpath.
<code>@Configuration
public class PropertyCondition {
@Bean
@ConditionalOnResource(resources = {"classpath:config.properties"})
public AnimalService animalService() {
return new AnimalService();
}
}</code>The bean is created only when config.properties is present in the classpath.
6. Web Application Conditions
Use @ConditionalOnWebApplication / @ConditionalOnNotWebApplication to configure beans based on whether the application is a web application. @ConditionalOnWarDeployment / @ConditionalOnNotWarDeployment target traditional WAR deployments.
<code>@Configuration
public class PropertyCondition {
@Bean
@ConditionalOnWebApplication(type = Type.REACTIVE)
public AnimalService animalService() {
return new AnimalService();
}
}</code>The bean is created only when the current environment is reactive (i.e., the project includes spring-webflux and not the servlet‑based web stack).
7. SpEL Expression Conditions
@ConditionalOnExpression activates a bean based on the result of a SpEL expression.
<code>@Configuration
public class PropertyCondition {
@Bean
@ConditionalOnExpression("#{'true'.equals('${pack.config.enabled}')}" )
public AnimalService animalService() {
return new AnimalService();
}
}</code>8. Custom Condition
Define a custom condition by implementing Condition and creating a meta‑annotation that uses @Conditional with the custom class.
<code>public class PackConditionProperty implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Boolean result = context.getEnvironment().getProperty("pack.config.enabled", Boolean.class, true);
return result;
}
}</code> <code>@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Conditional(PackConditionProperty.class)
public @interface PackCondition {
}</code>Apply the custom annotation to a configuration class or bean method to enforce the condition.
That concludes the article. Hope it helps!
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.