Spring @ConditionalOnProperty Example

Introduction

We will create examples on Spring @ConditionalOnProperty. The @ConditionalOnProperty annotation allows to load beans conditionally depending on a certain environment property or configuration of a property. Use the prefix and name attributes to specify the property that should be checked. By default, any property that exists and is not equal to false is matched. You can also create more advanced checks by using the havingValue and matchIfMissing attributes.

Prerequisites

Eclipse 2019-06 (4.12), Java 12, Gradle 5.6, Spring Boot 2.1.7

Creating Project

Create a gradle based project in Eclipse with the project name as spring-conditional-on-property.

Updating Build Script

The default generated build.gradle script does not include required dependencies, so we will update the build script as follows to include the spring boot dependencies.

buildscript {
	ext {
		springBootVersion = '2.1.7.RELEASE'
	}
    repositories {
    	mavenLocal()
    	mavenCentral()
    }
    dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
sourceCompatibility = 12
targetCompatibility = 12
repositories {
	mavenLocal()
    mavenCentral()
}
dependencies {
	implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
}

Creating Service Class

We will create simple service class without any methods in it. Ideally this service class will have some methods to perform your project’s business operations.

package com.roytuts.spring.conditional.on.property;
public class SpringService {
}

Creating Spring Config Class

We will create Spring Config class with the below source code.

We have used here prefix and name to denote the configuration property. Therefore the actual property name is module.enabled.

We have matchIfMissing = true in the @ConditionalOnProperty and it means that if the property module.enabled does not exist, it will still be loaded.

The SpringService is only loaded if the module.enabled property has the value true. So in the following scenario the SpringService will be loaded.

package com.roytuts.spring.conditional.on.property;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
	@Bean
	@ConditionalOnProperty(prefix = "module", name = "enabled", matchIfMissing = true)
	public SpringService springService() {
		return new SpringService();
	}
}

Creating Main Class

A class with main method is enough to run the Spring Boot application.

package com.roytuts.spring.conditional.on.property;
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 SpringConditionalOnPropertyApp implements CommandLineRunner {
	@Autowired
	private SpringService springService;
	public static void main(String[] args) {
		SpringApplication.run(SpringConditionalOnPropertyApp.class, args);
	}
	@Override
	public void run(String... args) throws Exception {
		System.out.println("Spring service fully qualified class name: " + springService.getClass());
	}
}

Testing the Application

On executing the main class you will get below output:

Spring service fully qualified class name: class com.roytuts.spring.conditional.on.property.SpringService

Other Scenarios

Now we will work with other scenarios.

For example let’s remove the tag matchIfMissing = true, i.e., @ConditionalOnProperty(prefix = "module", name = "enabled") and execute the main class. You will get the following error:

The following candidates were found but could not be injected:
	- Bean method 'springService' in 'SpringConfig' not loaded because @ConditionalOnProperty (module.enabled) did not find property 'enabled'

Why? Because you removed the matchIfMissing = true and you did not configure the property in properties file.

So put the property module.enabled=true into src/main/resources/application.properties file.

Now executing main class will not give any error and SpringService bean will be loaded.

Let’s say we have configured with havingValue = "true" as shown below:

@ConditionalOnProperty(prefix = "module", name = "enabled", havingValue = "true")

So if the property has value true then only SpringService bean will be loaded.

Now if you make havingValue = "false" then your bean SpringService will not be loaded and you will see below error:

The following candidates were found but could not be injected:
	- Bean method 'springService' in 'SpringConfig' not loaded because @ConditionalOnProperty (module.enabled=false) found different value in property 'enabled'

If you do not configure the property in properties file and havingValue = "true" with matchIfMissing = true does not make sense.

You can also use only @ConditionalOnProperty(prefix = "module", value = "enabled") to load the SpringService because the value of module.enabled is true (module.enabled=true) in the properties file.

But if you configure as module.enabled=false, then SpringService bean will not be loaded and you will get below error.

The following candidates were found but could not be injected:
	- Bean method 'springService' in 'SpringConfig' not loaded because @ConditionalOnProperty (module.enabled) found different value in property 'enabled'

You can also pass as value in place of name. You can also pass multiple names or multiple values but prefix will be only one.

To pass value instead of name, you can use @ConditionalOnProperty(prefix = "module", value = "enabled").

To pass multiple names or values you can use @ConditionalOnProperty(prefix = "module", name = {"enabled", "dynamic"}).

Source Code

download source code

Thanks for reading.

Related posts

One Thought to “Spring @ConditionalOnProperty Example”

  1. aswini kumar parida

    hey its a good article on @ConditionalonProperty. If i move these property to Git repo and change it dynamically and refresh through actuator, will this annotation work?

Leave a Comment