Spring Boot @ConditionalOnProperty Annotation Example
In this section we will learn about @ConditionalOnProperty Annotation.
It may be useful in many cases for example enable/disable service if specific property is available.
The @ConditionalOnProperty annotation may be used on any class annotated with @Configuration, @Component, @Service & @Repository or on methods annotated with @Bean.
1. Using @ConditionalOnProperty on @Bean method
To illustrate the use of @ConditionalOnProperty, we will develop a basic notification system. To keep things simple for now, let's assume we want to send email notifications.
Suppose we have a key = notification.service and value = twitter in the application.properties file.
notification.service=twitter
Next we'll need to create a simple service to send a notification. For example, consider the Notification Sender interface:
public interface NotificationService {
String sendNotification(String message);
}
Next, let's introduce the implementation of the Notification Sender interface for sending our emails:
public class EmailNotificationService implements NotificationService {
@Override
public String sendNotification(String message) {
return "Email Notification: " + message;
}
}
Now let's see how to use the @ConditionalOnProperty annotation. Let's configure the Notification Sender bean so that it is loaded only if the notification.service property is defined:
@ConditionalOnProperty
(prefix = "notification",
name = "service")
@Bean(name = "emailNotification")
public NotificationService emailNotificationService()
{
return new EmailNotificationService();
}
As we can see, the prefix and name attributes are used to indicate the configuration property to be checked.
Suppose we want to add another notification service – for example, a service that will allow us to send Twitter notifications.
To do this, we need to create another Notification Sender implementation:
public class TwitterNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "Twitter Notification: " + message;
}
}
public class TwitterNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "Twitter Notification: " + message;
}
}
Since we have two implementations, let's see how we can use @ConditionalOnProperty to load the correct NotificationSender bean conditionally.
For this purpose, the annotation specifies an attribute that has the value. Interestingly enough, it defines the value that a property must have to add a particular component to the Spring IOC container.
Now let's clarify under what conditions we want to register the Twitter notification implementation in the context:
@ConditionalOnProperty
(prefix = "notification",
name = "service",
havingValue = "twitter")
@Bean(name = "twitterNotification")
public NotificationService twitterNotificationService()
{
return new TwitterNotificationService();
}
With the having Value attribute, we made it clear that we want to load the Twitter notification only when the notification.service is set to twitter.
2. Using @ConditionalOnProperty on @Service class
Suppose we want to add another notification service – for example, a service that will allow us to send SMS notifications.
To do this, we need to create another Notification Sender implementation:
@Service("smsNotification")
@ConditionalOnProperty
(prefix = "notification",
name = "service")
public class SMSNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "SMS Notification: " + message;
}
}
@Service("smsNotification")
@ConditionalOnProperty
(prefix = "notification",
name = "service")
public class SMSNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "SMS Notification: " + message;
}
}
As we can see, the prefix and name attributes are used to indicate the configuration property to be checked.
@ConditionalOnProperty has another attribute called matchIfMissing. If true it will match the condition and execute the annotated code when property itself is not available in environment.
The following example creates a Spring Boot web application which uses @ConditionalOnProperty annotation.
Project Directory
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-conditionalonproperty-annotation-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-conditionalonproperty-annotation-example</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
notification.service=twitter
notification.service=twitter
NotificationService.java
package com.knf.dev.demo.service;
public interface NotificationService {
String sendNotification(String message);
}
package com.knf.dev.demo.service;
public interface NotificationService {
String sendNotification(String message);
}
EmailNotificationService.java
package com.knf.dev.demo.service;
public class EmailNotificationService implements NotificationService {
@Override
public String sendNotification(String message) {
return "Email Notification: " + message;
}
}
package com.knf.dev.demo.service;
public class EmailNotificationService implements NotificationService {
@Override
public String sendNotification(String message) {
return "Email Notification: " + message;
}
}
TwitterNotificationService.java
package com.knf.dev.demo.service;
public class TwitterNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "Twitter Notification: " + message;
}
}
package com.knf.dev.demo.service;
public class TwitterNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "Twitter Notification: " + message;
}
}
AppConfig.java
package com.knf.dev.demo.config;
import com.knf.dev.demo.service.EmailNotificationService;
import com.knf.dev.demo.service.NotificationService;
import com.knf.dev.demo.service.TwitterNotificationService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@ConditionalOnProperty
(prefix = "notification",
name = "service")
@Bean(name = "emailNotification")
public NotificationService emailNotificationService()
{
return new EmailNotificationService();
}
@ConditionalOnProperty
(prefix = "notification",
name = "service",
havingValue = "twitter")
@Bean(name = "twitterNotification")
public NotificationService twitterNotificationService()
{
return new TwitterNotificationService();
}
}
package com.knf.dev.demo.config;
import com.knf.dev.demo.service.EmailNotificationService;
import com.knf.dev.demo.service.NotificationService;
import com.knf.dev.demo.service.TwitterNotificationService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@ConditionalOnProperty
(prefix = "notification",
name = "service")
@Bean(name = "emailNotification")
public NotificationService emailNotificationService()
{
return new EmailNotificationService();
}
@ConditionalOnProperty
(prefix = "notification",
name = "service",
havingValue = "twitter")
@Bean(name = "twitterNotification")
public NotificationService twitterNotificationService()
{
return new TwitterNotificationService();
}
}
SMSNotificationService.java
package com.knf.dev.demo.service;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service("smsNotification")
@ConditionalOnProperty
(prefix = "notification",
name = "service")
public class SMSNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "SMS Notification: " + message;
}
}
package com.knf.dev.demo.service;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
@Service("smsNotification")
@ConditionalOnProperty
(prefix = "notification",
name = "service")
public class SMSNotificationService implements NotificationService{
@Override
public String sendNotification(String message) {
return "SMS Notification: " + message;
}
}
Run the application - Application.java
package com.knf.dev.demo;
import com.knf.dev.demo.service.EmailNotificationService;
import com.knf.dev.demo.service.NotificationService;
import com.knf.dev.demo.service.SMSNotificationService;
import com.knf.dev.demo.service.TwitterNotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
NotificationService emailNotification;
@Autowired
NotificationService twitterNotification;
@Autowired
NotificationService smsNotification;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(emailNotification.
sendNotification("Email message"));
System.out.println(twitterNotification.
sendNotification("Twitter message"));
System.out.println(smsNotification.
sendNotification("SMS message"));
}
}
Application is the entry point that sets up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning.
Let's run this Spring boot application from either IntelliJ IDEA IDE by right click - Run 'Application.main()'
Or you can use the below maven command to run:
mvn spring-boot:run
Console Output:
Email Notification: Email message
Twitter Notification: Twitter message
SMS Notification: SMS message
Download Source Code
More related topics,