Spring @Conditional Annotation Example

0

Spring @Conditional annotation allows us to register components based on the outcome of one or more conditions. We will specify the conditions in @Conditional annotation. Each condition is of type Condition and implements match(). Unless all the conditions return true the component will not be eligible for registration.

Spring Condition Example

Let’s create a simple Condition object. The condition returns true if ‘beanA’ is registered.

IfBeanAExistsCondition:

package com.javarticles.spring.annotations;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class IfBeanAExistsCondition implements Condition {

    public boolean matches(ConditionContext context,
            AnnotatedTypeMetadata metadata) {
        return context.getBeanFactory().containsBeanDefinition("beanA");
    }

}

In the below example, we try to register BeanA and BeanB. Registration of BeanB depends on the condition that BeanA is already registered.

    @Configuration("beanB")
    @Conditional(IfBeanAExistsCfgCondition.class)
    static class BeanB {
    }

For the sake of the example, we create application context thrice.

  1. When we create the context first time we register both the beans. Since BeanA is first registered, BeanB too gets registered as the condition is able to find “beanA”.
  2. Second time, we only register BeanB. Here the condition will fail as BeanA is not registered.
  3. Third time, we register BeanB and then BeanA. Even though beanA gets registered eventually, it is not yet registered when the container first tries to register BeanA so the condition fails and container skips registering BeanB. To avoid this problem, we need a finer condition that implements ConfigurationCondition so that one exercise a control over when the condition be evaluated during parsing stage or during the bean registration stage.

SpringConditionalAnnotationExample:

package com.javarticles.spring.annotations;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

public class SpringConditionalAnnotationExample {

    public static void main(String[] args) {
        loadContextAndVerifyBeans(BeanA.class, BeanB.class);
        loadContextAndVerifyBeans(BeanB.class);
        loadContextAndVerifyBeans(BeanB.class, BeanA.class);
    }

    private static void loadContextAndVerifyBeans(Class<?>...classToRegister) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        try {
            ctx.register(classToRegister);
            ctx.refresh();
            System.out.println("Has beanA? " + ctx.containsBean("beanA"));
            System.out.println("Has beanB? " + ctx.containsBean("beanB"));
        } finally {
            ctx.close();
        }
    }

    @Configuration("beanA")
    static class BeanA {
    }

    @Configuration("beanB")
    @Conditional(IfBeanAExistsCondition.class)
    static class BeanB {
    }
}

Output:

Jan 29, 2016 11:02:31 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.spring[email protected]4783da3f: startup date [Fri Jan 29 23:02:31 IST 2016]; root of context hierarchy
Has beanA? true
Has beanB? true
Jan 29, 2016 11:02:31 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
INFO: Closing org.spring[email protected]4783da3f: startup date [Fri Jan 29 23:02:31 IST 2016]; root of context hierarchy
Jan 29, 2016 11:02:31 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.spring[email protected]2641e737: startup date [Fri Jan 29 23:02:31 IST 2016]; root of context hierarchy
Has beanA? false
Has beanB? false
Jan 29, 2016 11:02:31 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
INFO: Closing org.spring[email protected]2641e737: startup date [Fri Jan 29 23:02:31 IST 2016]; root of context hierarchy
Jan 29, 2016 11:02:31 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.spring[email protected]df27fae: startup date [Fri Jan 29 23:02:31 IST 2016]; root of context hierarchy
Jan 29, 2016 11:02:31 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
INFO: Closing org.spring[email protected]df27fae: startup date [Fri Jan 29 23:02:31 IST 2016]; root of context hierarchy
Has beanA? true
Has beanB? false

Download the source code

This was an example about spring @Conditional annotation.

You can download the source code here: [email protected]
Share.

Comments are closed.