Tech Insights
Malindu De Alwis
March 5, 2023

Spring framework conditional Bean loading

Spring framework conditional Bean loading

Spring is a widely used open-source framework suitable for building various types of Java applications. In the Spring framework, a Spring Bean is an object that is created, managed, and destroyed by the Spring Container. Objects can be injected into the Spring Container through metadata, either via XML or annotations, eliminating the need for manual creation and management of instances. This process is known as inversion of control.

There are scenarios where it may be necessary to inject a Bean based on specific conditions. Examples of such cases include:

  • Customising the application
  • Running it on cloud or on-premises
  • Using the same application in multiple environments

To achieve the desired functionality, the @Conditional annotation is employed, which offers more flexibility than the @Profile annotation.

1. Example Scenario

Consider a Spring application that needs to support both cloud and on-premises deployments. In the cloud, the application operates as a standard web application with an embedded Tomcat server, while the on-premises version is deployed on JBoss as a WAR file. The application includes a service named FileService.java, which has different implementation logic depending on the deployment environment.

2. Configuration class.

A configuration class named AppConfig.java should be created to contain the Bean definitions for the FileService.java implementations.

View the code example

3. @ConditionalOnProperty.

In this case, the Bean is injected after verifying an application property against a specified value. The matchIfMissing = true property ensures that the expression matches even if the application property is absent.

View the code example

4. @ConditionalOnExpression.

Expressions can also be used for conditional Bean loading, as demonstrated in the following example. In addition to this, several predefined annotations can be utilised for conditional Bean loading, such as:

  • @ConditionalOnJava — Java version checking.
  • @ConditioalOnWarDeployment — For war deployments.
  • @ConditionalOnWebApplication — For web applications.
  • @ConditionalOnNotWebApplication — For none web applications.

View the code example

5. Custom conditions.

In some cases, it may be more convenient and readable to place the condition check in a separate file. To achieve this, the @Conditional annotation can be customised. Based on the return value of the matches method, the Bean will either be loaded or discarded.

If necessary, more complex logic can be incorporated using information about the current application context (ConditionContext) or the annotated class (AnnotatedTypeMetadata).

View the code example

The custom condition can then be added to AppConfig.java as shown below:

View the code example

6. Using Annotation on the component.

Instead of placing the condition inside the @Configuration class, it can be applied directly to the component class. In this case, the condition will be evaluated, and the Bean will be loaded if the condition is met.

View the code example

6. Running the application.

Implement the desired approach using any of the methods outlined above and run the application. The corresponding Bean will be loaded based on the specified condition. This can be verified through the logs or by debugging the application. You can find the complete code here.