The Spring Framework ships with a number of custom Java 5+ annotations.
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 { }
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.