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.
<?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.
package com.zetcode.bean; public interface MessageBean { String getMessage(); }
This is the MessageBean
.
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.
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.
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.
spring.main.banner-mode=off welcomebean.enabled=true
In the application.properties
file, we define the welcomebean.enabled
property.
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.
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.