Monday, August 21, 2023

What is @Conditional annotation in Spring Framework? Example Tutorial

Hello guys, if you want to know what is @Conditional annotation in Spring Framework and Spring Boot, and how to use it then you have come to the right place. Earlier, I have shared best free courses to learn Spring Framework and Spring Boot, and in this article, you'll learn what they are, how to use them with practical examples. Spring 4.0 introduced the @Conditional annotation that is used for conditional checking for bean registration. This annotation offers more support than the @Profile annotation provided by the spring framework and most of the Spring Boot matching is attributed to this annotation. It allows you to setup features based upon certain conditions like presence of a class in classparth or a JAR File which is how Spring Boot Auto-configuration works.

The majority of @Conditional annotation users are,
  • Conditions based on Bean definition or object present in the application.
  • Conditions based on user-defined strategies
So in this tutorial, you will learn how to use predefined conditional annotations, combine them with different conditions as well as create our custom, condition-based annotations.

Java developers need to have a separate class that implements the Condition interface. Basically, the interface has matches() method and the application’s condition inside this method.



1. What is Conditional Interface in Spring Framework?

From the Spring API Doc, condition interface is a single condition must be maintained in order for a component to be registered.

Conditions are checked immediately before the bean definition is due to be registered and are free to veto registration based on any criteria that can be determined at that point.

Conditions must follow the same restrictions as BeanFactoryPostProcessor and take care to never interact with bean instances. For more fine-grained control of conditions that interact with @Configuration beans consider the ConfigurationCondition interface.

Let us see an easy code snippet to understand this interface,

public class ConditionClass implements Condition {

@Override
public boolean matches(final ConditionContext context,
                       final AnnotatedTypeMetadata metadata) {
  return true;
 }
}




2. Spring @Conditional Annotation Example

Let's say you only want to construct a bean if a certain condition is present in the property file; otherwise, you don't want to create it. The @Conditional annotation can be used to create the bean in a conditional manner. 

So I'm going to make a project to teach the @Conditional annotation.

What is @Conditional annotations in Spring Framework? Example Tutorial


In this example, we are not going to store the values in any database. So only used the spring-boot-starter dependency as shown in the following pom.xml file.



<?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>2.5.2</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.example</groupId>

<artifactId>studentproject</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>studentproject</name>

<description>Demo project for Spring Boot</description>

<properties>

<java.version>11</java.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</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>


StudentBean class

This is an empty bean class to show you the process.

public class StudentBean {

 private String name;
 public String getName() {
  return name;
 }

public void setName(String name) {
  this.name = name;
  }
}






3. TestBeanCondition Class

This is the class that implements the Condition interface and provides the condition for creating the StudentBean. As you can see in the matches method it checks if the environment contains the property “student”.

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class StudentBeanCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
   Environment environment = context.getEnvironment();
   return environment.containsProperty("student");
  }
}




4. StudentBeanConfig class

This is the class where TestBean is created, you can see the @Conditional annotation used here with the class that provides the condition.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value="classpath:config/test.properties", ignoreResourceNotFound=true)
public class StudentBeanConfig {

@Bean
@Conditional(StudentBeanCondition.class)
public StudentBean studentBean() {
    System.out.println("student bean creation");
    return new StudentBean();
  }
}



5. Test the code

Then test the code using the below code snippet.

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class StudentApplication {

public static void main( String[] args ){
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext
(StudentBeanConfig.class);

  StudentBean sb = (StudentBean)context.getBean("studnetBean");
  sb.setName("Angela");
  System.out.println("" + sb.getName());
  context.close();
  }
}




Output

If everything goes well, the code shows the bean with the testing quotes and the student name.





That's all about what is @Conditional annotation in Spring and How to use it. The @Conditional annotation receives a class name that implements the Condition interface and creates the bean if that condition is matched.

If the condition you're seeking to build is merely the inverse of another condition, you can extend from it and override the matches method as the inverse of executing the parent class's matches method.

You must expressly define the condition. Spring will register the bean and add it to the application context if these conditions are met. That is all for this tutorial and I hope the article served you whatever you were looking for. 

Happy Learning and do not forget to share!


Other Spring Framework Articles and Resources you may like:
Thanks for reading this article so far, if you find this Spring @Conditional examples useful then please share them with your friends and colleagues. If you have any questions or feedback, please drop a note. 

P. S. - If you are new to Spring Framework and want to learn Spring Framework in depth and looking for best resources like online courses then you can also checkout this list of best Spring Framework courses for Java programmers to master Spring Framework and Spring Boot in depth. 

1 comment:

Feel free to comment, ask questions if you have any doubt.