Spring Framework
Bean Declaration
Conditional Configuration
Application Profiles
Java Development

How to conditionally declare Bean when multiple profiles are not active?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

markdown
1In Spring Framework, managing different environments or configurations is frequently handled using profiles. Profiles enable you to execute certain beans in particular environments while excluding them from others. Sometimes, we encounter situations where we need to declare a Bean only if multiple profiles are not active. Understanding how to conditionally declare Beans in such cases ensures that unnecessary components don’t clutter the application context, reducing resource consumption and potential conflicts.
2
3## Conditional Bean Declaration
4
5Conditional Bean declaration in the Spring framework can effectively be managed using `@Conditional`, `@Profile`, and custom conditions. In this article, we will focus on how to utilize these tools for the specific case of multiple inactive profiles.
6
7### Scenario Explanation
8
9Suppose you have three environments: `dev`, `test`, and `prod`. You have a Bean which should only be active if neither `dev` nor `test` profiles are active. Such a setup can be beneficial when you want to have certain configurations or services running only in the production environment without needing to explicitly mention the `prod` profile.
10
11### Using `@Profile` with a Logical Not
12
13Spring provides the `@Profile` annotation to link a bean to a specific profile. However, the challenge arises when checking for non-active profiles. Unfortunately, `@Profile` doesn’t support "not" logic directly. Thus, to achieve the necessary conditional bean declaration, you can use custom conditions.
14
15### Implementing Custom Conditional Logic
16
17To make a bean conditional on the absence of multiple profiles, we can leverage the `@Conditional` annotation alongside a custom condition class.
18
19#### Custom Condition Class
20
21First, create a class implementing the `Condition` interface:
22
23```java
24import org.springframework.context.annotation.Condition;
25import org.springframework.context.annotation.ConditionContext;
26import org.springframework.core.type.AnnotatedTypeMetadata;
27import java.util.Arrays;
28import java.util.List;
29
30public class ProfilesNotActiveCondition implements Condition {
31    @Override
32    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
33        List<String> activeProfiles = Arrays.asList(context.getEnvironment().getActiveProfiles());
34        return !activeProfiles.contains("dev") && !activeProfiles.contains("test");
35    &#125;
36&#125;

In this implementation:

  • We obtain the list of currently active profiles.
  • The condition returns true if neither dev nor test profiles are active.

Condition Application with @Conditional

Now we annotate the desired bean with the @Conditional annotation:

java
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.context.annotation.Conditional;
4
5@Configuration
6public class AppConfig &#123;
7
8    @Bean
9    @Conditional(ProfilesNotActiveCondition.class)
10    public MyBean myConditionalBean() &#123;
11        return new MyBean();
12    &#125;
13&#125;
14
15class MyBean &#123;
16    // Bean logic here
17&#125;

In this configuration:

  • MyBean will only be initialized if neither dev nor test profiles are active.
  • This approach offers a clean and maintainable mechanism to handle complex profile conditions.

Summary

The table below summarizes the key actions and outcomes discussed:

ComponentDescription
ProfilesNotActiveConditionCustom condition to check inactive profiles.
@ConditionalAnnotation used to apply custom conditions.
@ProfileAnnotation to directly bind Beans to specific profiles.
Active Profiles RequirementEnsure neither dev nor test profiles are active.
Resultant Bean InitializationMyBean is initialized only when the specified profiles are not active.

Additional Considerations

  • Performance: Ensure minimal logic in the condition class to avoid unnecessary overhead during condition evaluation.
  • Security: Ensure environments are properly configured to prevent accidental activation of unwanted beans.
  • Testing: Practice extensive testing across different environments to ensure conditions behave as expected.

Conclusion

Using custom conditions for conditional bean declarations when dealing with multiple inactive profiles allows for more granular and flexible control over your application context. This approach not only adheres to the separation of concerns principle but also ensures that your Spring application efficiently adapts to its environment-specific requirements.

 

Course illustration
Course illustration

All Rights Reserved.