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

Download

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.

Share

Related posts

No comments

Leave a comment