ZetCode

Spring Boot Conditional beans

last modified July 6, 2020

Spring Boot Conditional beans tutorial shows how to register beans into the Spring Boot application context based on conditions.

Spring Boot is a popular application framework for creating enterprise application in Java, Kotlin, or Groovy.

@Conditional

The @Conditional annotation indicates that a component is only registered into the application context when all the specified conditions match. If a @Configuration class is marked with @Conditional, all of the @Bean methods, @Import annotations, and @ComponentScan annotations associated with that class will be subject to the conditions.

Spring provides plenty of conditional annotations out-of-the-box, including @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnBean, @ConditionalOnProperty, @ConditionalOnNotWebApplication, and @ConditionalOnExpression.

Spring Boot Conditional beans example

In the following application, we have two beans that are registered based on conditions.

pom.xml
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── Application.java
│   │           ├── bean
│   │           │   ├── GenericMessage.java
│   │           │   ├── MessageBean.java
│   │           │   └── WelcomeMessage.java
│   │           ├── conf
│   │           │   └── AppConf.java
│   │           └── MyRunner.java
│   └── resources
│       └── application.properties
└── test
    └── java

This is the project structure of the Spring Boot application.

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
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootConditionalBeans</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <properties>
        <java.version>13</java.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
    </parent>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

This is the Maven pom.xml file.

com/zetcode/bean/MessageBean.java
package com.zetcode.bean;

public interface MessageBean {

    String getMessage();
}

This is the MessageBean.

com/zetcode/bean/GenericMessage.java
package com.zetcode.bean;

public class GenericMessage implements MessageBean {

    private String message;

    public GenericMessage(String message) {

        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

This is a GenericMessage used for a generic message.

com/zetcode/bean/WelcomeMessage.java
package com.zetcode.bean;

public class WelcomeMessage implements MessageBean {

    private String message;

    public WelcomeMessage(String message) {

        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

The WelcomeMessage is suited for a welcome message.

com/zetcode/conf/AppConf.java
package com.zetcode.conf;

import com.zetcode.bean.GenericMessage;
import com.zetcode.bean.WelcomeMessage;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConf {

    @Bean
    @ConditionalOnProperty(name="welcomebean.enabled", havingValue="true")
    public WelcomeMessage welcomeBeanBean() {

        return new WelcomeMessage("Welcome!");
    }

    @Bean
    @ConditionalOnMissingBean(WelcomeMessage.class)
    public GenericMessage messageBean() {

        return new GenericMessage("Today is a beautiful day.");
    }
}

In the AppConf we have two beans that are defined based on conditions.

@Bean
@ConditionalOnProperty(name="welcomebean.enabled", havingValue="true")
public WelcomeMessage welcomeBeanBean() {

    return new WelcomeMessage("Welcome!");
}

With the @ConditionalOnProperty, the WelcomeMessage bean is registered only if there is a welcomebean.enabled property set to true.

@Bean
@ConditionalOnMissingBean(WelcomeMessage.class)
public GenericMessage messageBean() {

    return new GenericMessage("Today is a beautiful day.");
}

The GenericMessage is registered on condition that the WelcomeMessage is not.

resources/application.properties
spring.main.banner-mode=off
welcomebean.enabled=true

In the application.properties file, we define the welcomebean.enabled property.

com/zetcode/MyRunner.java
package com.zetcode;

import com.zetcode.bean.MessageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {

    @Autowired
    private MessageBean messageBean;

    @Override
    public void run(String... args) throws Exception {

        System.out.println(messageBean.getMessage());
    }
}

In MyRunner we autowire a message bean and print the message. Depending on the welcomebean.enabled property, we either get a welcome message or the generic message.

com/zetcode/Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

The Application sets up the Spring Boot application.

$ mvn -q spring-boot:run
...
Welcome!

We run the application.

In this tutorial, we have worked with conditional beans.

List Spring Boot tutorials.