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.
- 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”. - Second time, we only register
BeanB
. Here the condition will fail asBeanA
is not registered. - Third time, we register
BeanB
and thenBeanA
. Even thoughbeanA
gets registered eventually, it is not yet registered when the container first tries to registerBeanA
so the condition fails and container skips registeringBeanB
. To avoid this problem, we need a finer condition that implementsConfigurationCondition
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]