Spring @ConditionalOnBean Example
Conditional On Bean
I will create examples on Spring @ConditionalOnBean (condition on bean).
@Conditional… annotations. The @ConditionalOnBean annotation let a bean be included based on the presence of specific beans. By default Spring will search entire hierarchy (SearchStrategy.ALL).Prerequisites
Java 12/19/22, Maven 3.6.3/3.8.5/3.9.8, Spring Boot 2.1.7 – 2.4.5/3.1.5/3.5.4
Project Setup
Create a maven based project in your favorite IDE or tool with the project name as spring-conditional-on-bean.
I will update the build file (pom.xml) as follows to include the spring boot dependencies.
<?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-bean</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> Service Class
I 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.
public class SpringService {
} Examples on @ConditionalOnBean
I will create various ways of using @ConditionalOnBean annotation on the bean.
Simple Beans
I will create two beans which will be required to call on @ConditionalOnBean annotation because these annotated bean will be executed only when the required bean is found.
Bean – RequiredBean
I have used annotation @Component to get advantage of autowire.
@Component
public class RequiredBean {
} Bean – AnotherRequiredBean
@Component
public class AnotherRequiredBean {
} Examples – @ConditionalOnBean
I will create a Spring Config class and use annotation @ConditionalOnBean in various ways, such as, by name, type, value, search and will see how it works.
I will modify our Spring Config class for each type of example.
I will also create a main class to run our application. The source of the main class is given below. I will not modify the main class but I will run our main class after each modification to the Spring Config class.
@SpringBootApplication
public class SpringConditionalOnBeanApp implements CommandLineRunner {
@Autowired
private SpringService springService;
public static void main(String[] args) {
SpringApplication.run(SpringConditionalOnBeanApp.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Spring service fully qualified class name: " + springService.getClass());
}
} @ConditionalOnBean – by value
Here I will show @ConditionalOnBean by value in Spring Config class.
I will pass the class for the value value.
@Configuration
public class SpringConfig {
@Bean
@ConditionalOnBean(value = RequiredBean.class)
public SpringService springService() {
return new SpringService();
}
} Run the main class to see the result as shown below in the console.
Spring service fully qualified class name: class com.roytuts.spring.conditional.on.bean.SpringService Therefore to build a new instance of the SpringService class your RequiredBean class must exist.
@ConditionalOnBean – by name
I will now use by passing the bean name for the value name. Here I am passing single bean names but you can also pass multiple bean names and I will show on this after this example.
As I have annotated class RequiredBean with @Component and by default bean name is resolved as class name with initial letter in lower case, so you don’t need to define it separately.
@Configuration
public class SpringConfig {
@Bean
@ConditionalOnBean(name = "requiredBean")
public SpringService springService() {
return new SpringService();
}
} Now run the main class to see the below output:
Spring service fully qualified class name: class com.roytuts.spring.conditional.on.bean.SpringService Now if you change as @ConditionalOnBean(name = "RequiredBean") then you will see below error in the console because bean with name RequiredBean does not exist.
Bean method 'springService' in 'SpringConfig' not loaded because @ConditionalOnBean (names: RequiredBean; SearchStrategy: all) did not find any beans named RequiredBean @ConditionalOnBean – by name
I had passed single bean name in the above example and now I will pass multiple names and check the results.
@Configuration
public class SpringConfig {
@Bean
@ConditionalOnBean(name = { "requiredBean", "anotherRequiredBean" })
public SpringService springService() {
return new SpringService();
}
} You will find same output in the console with new SpringService instance.
@ConditionalOnBean – by type
Next I will pass value by type in the @ConditionalOnBean annotation.
@Configuration
public class SpringConfig {
@Bean
@ConditionalOnBean(type = "com.roytuts.spring.conditional.on.bean.RequiredBean")
public SpringService springService() {
return new SpringService();
}
} You will get the same output as for the by name.
@ConditionalOnBean – by search
Strategy to decide if the application context hierarchy (parent contexts) should be considered. It the search strategy. The default search strategy is ALL. Others are ANCESTORS and CURRENT.
@Configuration
public class SpringConfig {
@Bean
@ConditionalOnBean(search = SearchStrategy.CURRENT, type = "com.roytuts.spring.conditional.on.bean.RequiredBean")
public SpringService springService() {
return new SpringService();
}
} You will get the same output as for the by name.
@ConditionalOnBeandoes not prevent@Configurationclasses from being created.
No comments
Leave a comment