The @ConditionalOnProperty
annotation in Spring Boot is a powerful tool for conditionally enabling or disabling beans, configurations, or auto-configurations based on the presence or value of a property in the application's configuration files (e.g., application.properties
or application.yml
).
This guide covers everything you need to know about @ConditionalOnProperty
, including:
- Basic usage
- Attribute explanations
- Advanced use cases
- Best practices
- Common pitfalls
1. Basic Usage of @ConditionalOnProperty
The annotation checks if a specified property exists, has a certain value, or meets a condition before allowing a bean or configuration to be loaded.
Example: Simple Property Check
@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureConfiguration {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
- Behavior: The
MyService
bean is only created iffeature.enabled=true
inapplication.properties
.
application.properties
feature.enabled=true
2. Key Attributes of @ConditionalOnProperty
Attribute | Description | Default Value |
---|---|---|
name / value | The name of the property to check. | (Required) |
havingValue | The expected value of the property. | (Optional, checks only existence if omitted) |
matchIfMissing | Whether the condition should pass if the property is missing. | false |
prefix | A prefix for the property name (used with name ). | (Optional) |
3. Different Use Cases with Examples
Case 1: Check Property Existence (No havingValue
)
@Bean
@ConditionalOnProperty("logging.enabled")
public LoggingService loggingService() {
return new LoggingService();
}
- Behavior: Bean is created if
logging.enabled
exists (regardless of value).
Case 2: Check Property with Specific Value
@Bean
@ConditionalOnProperty(name = "cache.type", havingValue = "redis")
public CacheService redisCache() {
return new RedisCache();
}
- Behavior: Only loads if
cache.type=redis
.
Case 3: Handle Missing Property (matchIfMissing
)
@Bean
@ConditionalOnProperty(name = "security.enabled", matchIfMissing = true)
public SecurityService securityService() {
return new DefaultSecurityService();
}
- Behavior: Loads if
security.enabled
istrue
or missing.
Case 4: Using prefix
for Cleaner Property Names
@Configuration
@ConditionalOnProperty(prefix = "app", name = "mode", havingValue = "dev")
public class DevConfig {
@Bean
public Environment devEnvironment() {
return new DevEnvironment();
}
}
- Property:
app.mode=dev
triggers this configuration.
4. Advanced Scenarios
Combining Multiple Conditions
You can combine @ConditionalOnProperty
with other @Conditional
annotations:
@Bean
@ConditionalOnProperty(name = "db.enabled")
@ConditionalOnClass(DataSource.class)
public DataSource dataSource() {
return new HikariDataSource();
}
- Behavior: Only loads if
db.enabled
is true andDataSource
class is available.
Using in @Configuration
vs @Bean
- On a
@Configuration
class: Controls whether the entire configuration is loaded. - On a
@Bean
method: Controls only that specific bean.
Negating Conditions (Using @ConditionalOnMissingProperty
)
Spring Boot does not provide a direct @ConditionalOnMissingProperty
, but you can simulate it:
@Bean
@ConditionalOnProperty(name = "legacy.mode", havingValue = "false", matchIfMissing = true)
public ModernService modernService() {
return new ModernService();
}
- Behavior: Loads if
legacy.mode
isfalse
or missing.
5. Best Practices
β
Use prefix
for grouped properties (e.g., app.feature.enabled
).
β
Prefer matchIfMissing = false
for strict checks (unless default behavior is needed).
β
Document expected properties in application.properties
or README
.
β Avoid overly complex conditions (use @Profile
or custom conditions if needed).
6. Common Pitfalls & Troubleshooting
Issue 1: Bean Not Loading
- Check:
- Property name is correct (
@ConditionalOnProperty
is case-sensitive). - Property is in the right
.properties
/.yml
file. - No typos in
havingValue
.
- Property name is correct (
Issue 2: Unexpected Bean Activation
- Cause:
matchIfMissing = true
may cause beans to load unexpectedly. - Fix: Set
matchIfMissing = false
if the property is required.
Issue 3: YAML vs Properties Syntax
- YAML Example:feature: enabled: true
- Properties Equivalent:feature.enabled=true
7. Comparison with Other Annotations
Annotation | Purpose | Example |
---|---|---|
@ConditionalOnProperty | Checks property value | @ConditionalOnProperty(name="feature.on") |
@Profile | Activates based on Spring profile | @Profile("dev") |
@ConditionalOnClass | Checks if a class is available | @ConditionalOnClass(DataSource.class) |
@ConditionalOnMissingBean | Loads if a bean is missing | @ConditionalOnMissingBean(DataSource.class) |
8. Conclusion
The @ConditionalOnProperty
annotation is a flexible way to conditionally control bean creation in Spring Boot. By mastering its attributes (name
, havingValue
, matchIfMissing
, prefix
), you can build dynamic, environment-aware applications.
Final Example (Combining Concepts)
@Configuration
@ConditionalOnProperty(
prefix = "module",
name = "analytics",
havingValue = "enabled",
matchIfMissing = false
)
public class AnalyticsConfig {
@Bean
public AnalyticsService analyticsService() {
return new GoogleAnalyticsService();
}
}
- Property Required:
module.analytics=enabled