Spring Boot Conditional Bean Loading with @ConditionalOnExpression and SpEL
Overview
In this tutorial,
you’ll learn how to conditionally load Spring beans using the @ConditionalOnExpression annotation in Spring Boot. This powerful feature allows you to include configuration based on the evaluation of a Spring Expression Language (SpEL) expression. For example, you can load a module only when specific conditions defined in your application.properties file are met. This approach is especially useful for creating modular applications where components are activated dynamically based on runtime configuration.SpEL or Spring Expression Language which can be used to query property value from properties file using $, or manipulate Java object and its attributes at runtime using #. Both modifiers $ and # can be used in spring XML configuration file directly, or can be used in Java source code with @Value annotation.
Project Setup
Create a Maven or Gradle project named spring-conditional-on-expression.
The following pom.xml file can be used for the maven based project:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.roytuts</groupId>
<artifactId>spring-conditional-on-expression</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>22</maven.compiler.release>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.4</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project> Module Class
Create a simple Module class just to check whether it is loaded or not based on SpEL condition.
public class Module {
} Application Properties
Create an application.properties file under src/main/resources folder with below content:
module.enabled=true
module.submodule.enabled=true Spring Configiration
Create below SpringConfig class to load the Module class conditionally.
So if SpEL conditions are evaluated to true, then only Module class will be loaded otherwise not.
@Configuration
@ConditionalOnExpression(value = "${module.enabled} and ${module.submodule.enabled}")
class SpringConfig {
@Bean
public Module module() {
return new Module();
}
} Main Application Class
Create main class to run the Spring Boot application.
@SpringBootApplication
public class SpringConditionalOnExpressionApp implements CommandLineRunner {
@Autowired
private ApplicationContext applicationContext;
public static void main(String[] args) {
SpringApplication.run(SpringConditionalOnExpressionApp.class, args);
}
@Override
public void run(String... args) throws Exception {
String[] beans = applicationContext.getBeanDefinitionNames();
Arrays.sort(beans);
boolean contains = Arrays.stream(beans).anyMatch("module"::equalsIgnoreCase);
if (contains) {
System.out.println("Module loaded");
} else {
System.out.println("Module not loaded");
}
}
} Testing the Application
- If both properties are true, output will be:
Module loaded - If either is false, output will be:
Module not loaded
Now if you run the above main class, you will see below output:
Module loaded If you make false to any of the keys in the application.properties file then you will get below output:
Module not loaded Variations of SpEL Usage
OR Condition
You can also check if any of the values is true for the keys in application.properties file in the following way.
@ConditionalOnExpression(value = "${module.enabled} or ${module.submodule.enabled}") By executing the main class you will get below output:
Module loaded Default Values
You can also pass default value to the SpEL using the following way:
@ConditionalOnExpression(value = "${module.enabled:true} and ${module.submodule.enabled:true}") Equality Check
You can also check for equality of the expression values as shown below:
@ConditionalOnExpression("'${module.enabled}'.equals('${module.submodule.enabled:true}')") Static Method Evaluation
You can use @ConditionalOnExpression on class object’s methods, i.e., @ConditionalOnExpression("#{T(java.lang.Math).random() gt 0}").
Remember the method has to be static.
For the above case, if the random value is greater than 0 then only module will be loaded.
Custom Class Method
Let’s say you have the following class:
public class SpEL {
public static String getHello() {
return "hello";
}
} And you want to use method from the above class on @ConditionalOnExpression. Then you can use the following:
@ConditionalOnExpression("#{T(com.roytuts.spring.conditional.on.expression.SpEL).getHello() eq 'hello'}") or
@ConditionalOnExpression("#{T(com.roytuts.spring.conditional.on.expression.SpEL).getHello()?.equals('hello')}") For the above case, the module is loaded only when getHello() returns hello.
Source Code
Conclusion
The @ConditionalOnExpression annotation in Spring Boot provides a flexible way to conditionally load beans based on runtime configuration using Spring Expression Language (SpEL). This approach is ideal for modular applications where components need to be activated or deactivated dynamically. By leveraging SpEL, developers can write expressive conditions, integrate static or custom logic, and fine-tune application behavior without hardcoding dependencies. Whether you’re building microservices or feature-rich enterprise apps, this technique helps keep your configuration clean, maintainable, and adaptable.
No comments
Leave a comment