Ebooks

Spring Boot Conditional beans

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.