Conditional Annotation in Spring 4.0

SHARE & COMMENT :

In this article I shall throw some light on one of the new features of Spring 4Conditional Annotation Type. In the earlier versions of Spring you could handle conditions as below:

  • In Spring with versions earlier to 3.1, you had to use Spring Expression Language (SPeL).
  • With Spring 3.1, a new feature called profiles was introduced which helped us to handle conditions.

Let us see each of these approaches and then understand the Conditional Annotation type in Spring 4.

Spring Expression Language (SPeL)

The SPeL has a Ternary Operator (If-Then-Else) which can be used as conditional statement in your configuration file (spring.xml) as in the example below:

<bean id="flag">
   <constructor-arg value="#{systemProperties['system.propery.flag'] ?: false }" />
</bean>
<bean id="bean">
    <property name="property" value="#{ flag ? 'yes' : 'no' }"/>
</bean>

I have Spring bean (MyBean) whose value depends on the value of a property (property). MyBean is set dynamically based on environment it runs.

Using Profiles

The second approach as mentioned would be to use of profiles which got introduced since Spring 3.1.

<!-- default configuration - will be loaded if no profile is specified -->
<!-- This will only work if it's put at the end of the configuration file -->
<!-- so no bean definitions after that -->
<beans profile="default">
     <import resource="classpath:default.xml" />
</beans>
<!-- some other profile -->
<beans profile="otherProfile">
    <import resource="classpath:other-profile.xml" />
</beans>

Conditional Annotation Type In Spring 4

Now let us understand the Conditional Annotation type. This annotation will be introduced in Spring 4, which is set to release by the end of 2013. However, anyone can download the early access release and try the new features. As the official document defines the conditionals class as “Indicates that a component is is only eligible for registration when all specified conditions match”. The primary objective is to create the bean only after the set of conditions are met.

The declaration of Conditional interface is as below:

 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE, ElementType.METHOD)
 public @interface Conditional{
Class <!--?extends Condition-->[] value();
 }

The @Conditional annotation may be used in any of the following ways:

  1. as a type-level annotation on any class directly or indirectly annotated with @Component, including @Configuration classes.
  2. as a meta-annotation, for the purpose of composing custom stereotype annotations.
  3. as a method-level annotation on any @Bean method

If a @Configuration class is marked with @Conditional, all of the @Bean methods and @Import annotations associated with that class will be subject to the conditions.

The condition interface is as follows:


public interface Condition{
/** Determine if the condition matches.
* @param context the condition context
* @param metadata meta-data of the {@link AnnotationMetadata class} or
* {@link Method method} being checked.
* @return {@code true} if the condition matches and the component can be registered
* or {@code false} to veto registration.
*/
boolean matches(ConditionContext context, AnnotatedTypeMedata metadata);
}

Let’s see an example:


public class SystemPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return (System.getProperty("flag") != null);
}
}

class SystemPropertyAbsentCondition implements Condition {

@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return (System.getProperty("flag") == null);

}
}

Here we have two classes SystemPropertyCondition and SystemPropertyAbsentCondition. Both these classes implement Condition interface. The overridden method returns a boolean value based on the property flag.

Now lets define bean definitions one with positive condition and one that specifies the negative condition as below:


@Bean
@Conditional(SystemPropertyCondition.class)
public SampleService service1() {
return new SampleServiceImpl1();
}

@Bean
@Conditional(SystemPropertyAbsentCondition.class)
public SampleService service2() {
return new SampleServiceImpl2();
}

The Conditional annotation can also be used for modifying the behavior of Spring 3.1 based Profiles itself that I mentioned in above sections. Profiles is internally now based on meta-annotation based Conditional. @Profile annotation has been re factored.

Summary

In this article I have tried to consolidate the Conditional annotation type in Spring 4. Also note that condition annotations are not inherited. If a super class has the Conditional annotation, the sub classes will not have that conditions. If you try few examples listed above, it is easy for you to understand this concept. Hope you liked it.

Comments

comments

About Manisha Patil

Manisha S Patil, currently residing at Pune India. She is currently working as freelance writer for websites. She had earlier worked at Caritor Bangalore, TCS Bangalore and Sungard Pune. She has 5 years of experience in Java/J2EE technologies.

Comments

  1. How annotations works? Can we write a busineess logic in annotation?

  2. Whats the difference betweeen IOC & Dependency Injection?

  3. Thank you..

  4. Could you tell me the how to re-set the the form values after form submission & redirecting to same page. I am doing validation on server side whichever form controls entered values are correct then need to set back to text field. How to do it JSP or in Servlet. In .net I heard can be dont using view state is there any such features?

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better