27.2 Annotations

The Spring Framework ships with a number of custom Java 5+ annotations.

27.2.1 @Required

The @Required annotation in the org.springframework.beans.factory.annotation package can be used to mark a property as being 'required-to-be-set' (i.e. an annotated (setter) method of a class must be configured to be dependency injected with a value), else an Exception will be thrown by the container at runtime.

The best way to illustrate the usage of this annotation is to show an example:

public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;

    // a setter method so that the Spring container can 'inject' a MovieFinder
    @Required
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    
    // business logic that actually 'uses' the injected MovieFinder is omitted...
}

Hopefully the above class definition reads easy on the eye. Any and all BeanDefinitions for the SimpleMovieLister class must be provided with a value.

Let's look at an example of some XML configuration that will not pass validation.

<bean id="movieLister" class="x.y.SimpleMovieLister">
    <!-- whoops, no MovieFinder is set (and this property is @Required) -->
</bean>

At runtime the following message will be generated by the Spring container (the rest of the stack trace has been truncated).

Exception in thread "main" java.lang.IllegalArgumentException:
    Property 'movieFinder' is required for bean 'movieLister'.

There is one last little (small, tiny) piece of Spring configuration that is required to actually 'switch on' this behavior. Simply annotating the 'setter' properties of your classes is not enough to get this behavior. You need to enable a component that is aware of the @Required annotation and that can process it appropriately.

This component is the RequiredAnnotationBeanPostProcessor class. This is a special BeanPostProcessor implementation that is @Required-aware and actually provides the 'blow up if this required property has not been set' logic. It is very easy to configure; simply drop the following bean definition into your Spring XML configuration.

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

Finally, one can configure an instance of the RequiredAnnotationBeanPostProcessor class to look for another Annotation type. This is great if you already have your own @Required-style annotation. Simply plug it into the definition of a RequiredAnnotationBeanPostProcessor and you are good to go.

By way of an example, let's suppose you (or your organization / team) have defined an attribute called @ Mandatory. You can make a RequiredAnnotationBeanPostProcessor instance @Mandatory-aware like so:

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
    <property name="requiredAnnotationType" value="your.company.package.Mandatory"/>
</bean>

Here is the source code for the @Mandatory annotation. You will need to ensure that your custom annotation type is itself annotated with appropriate annotations for its target and runtime retention policy.

package your.company.package;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory {
}

27.2.2 Other @Annotations in Spring

Annotations are also used in a number of other places throughout Spring. Rather than being described here, these annotations are described in that section or chapter of the reference documentation to which they are most relevant.