You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
8.1 KiB
189 lines
8.1 KiB
<?xml version="1.0" encoding="UTF-8"?> |
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" |
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> |
|
<chapter id="metadata"> |
|
<title>Annotations and Source Level Metadata Support</title> |
|
|
|
<section id="metadata-introduction"> |
|
<title>Introduction</title> |
|
|
|
<para>Java 5 introduced source-level metadata called annotations to |
|
program elements, usually, classes and/or methods</para> |
|
|
|
<para>For example we might add metadata at the class level using the |
|
Spring's @Transactional annotation that is used to support Spring's |
|
declarative transaction management features.</para> |
|
|
|
<programlisting language="java">@Transactional |
|
public class PetStoreImpl implements PetStoreFacade, OrderService {</programlisting> |
|
|
|
<para>We could also add metadata to a method as follows:</para> |
|
|
|
<programlisting>public class PetStoreImpl implements PetStoreFacade, OrderService { |
|
|
|
. . . |
|
|
|
@Transactional |
|
public void insertOrder(Order order) { |
|
this.orderDao.insertOrder(order); |
|
this.itemDao.updateQuantity(order); |
|
} |
|
|
|
. . . |
|
}</programlisting> |
|
|
|
<para>The value of using annoations has been broadly embrassed by the JEE |
|
community. For example, it's much less verbose than the traditional XML |
|
deployment descriptors. While it is desirable to externalize some things |
|
from program source code, some important enterprise settings - notably |
|
transaction characteristics - arguably belong in program source. </para> |
|
|
|
<para>Spring uses Java 5 annotations thoughout the framework across a wide |
|
range of features such as DI, MVC, and AOP and supports JEE standard |
|
annotations such as @PreDestroy and @PostConstruct defined by JSR-250. |
|
This chapter describes the @Required attribute and provides links to other |
|
parts the documentation where the various attributes are described in more |
|
detail.</para> |
|
</section> |
|
|
|
<section id="metadata-annotations"> |
|
<title>Annotations</title> |
|
|
|
<para>The Spring Framework ships with a number of custom Java 5+ |
|
annotations.</para> |
|
|
|
<section id="metadata-annotations-required"> |
|
<title><interfacename>@Required</interfacename></title> |
|
|
|
<para>The <interfacename>@Required</interfacename> annotation in the |
|
<literal>org.springframework.beans.factory.annotation</literal> package |
|
can be used to <emphasis>mark</emphasis> a property as being |
|
<emphasis>'required-to-be-set'</emphasis> (i.e. an annotated (setter) |
|
method of a class must be configured to be dependency injected with a |
|
value), else an <classname>Exception</classname> will be thrown by the |
|
container at runtime.</para> |
|
|
|
<para>The best way to illustrate the usage of this annotation is to show |
|
an example:</para> |
|
|
|
<programlisting language="java">public class SimpleMovieLister { |
|
|
|
<lineannotation>// the <classname>SimpleMovieLister</classname> has a dependency on the <interfacename>MovieFinder</interfacename></lineannotation> |
|
private MovieFinder movieFinder; |
|
|
|
<lineannotation>// a setter method so that the Spring container can 'inject' a <interfacename>MovieFinder</interfacename></lineannotation> |
|
@Required |
|
public void setMovieFinder(MovieFinder movieFinder) { |
|
this.movieFinder = movieFinder; |
|
} |
|
|
|
<lineannotation>// business logic that actually 'uses' the injected <interfacename>MovieFinder</interfacename> is omitted...</lineannotation> |
|
}</programlisting> |
|
|
|
<para>Hopefully the above class definition reads easy on the eye. Any |
|
and all <interfacename>BeanDefinitions</interfacename> for the |
|
<classname>SimpleMovieLister</classname> class must be provided with a |
|
value.</para> |
|
|
|
<para>Let's look at an example of some XML configuration that will |
|
<emphasis role="bold">not</emphasis> pass validation.</para> |
|
|
|
<programlisting language="xml"><bean id="movieLister" class="x.y.SimpleMovieLister"> |
|
<lineannotation><!-- whoops, no MovieFinder is set (and this property is <interfacename>@Required</interfacename>) --></lineannotation> |
|
</bean></programlisting> |
|
|
|
<para>At runtime the following message will be generated by the Spring |
|
container (the rest of the stack trace has been truncated).</para> |
|
|
|
<programlisting>Exception in thread "main" java.lang.IllegalArgumentException: |
|
Property 'movieFinder' is required for bean 'movieLister'.</programlisting> |
|
|
|
<para>There is one last little (small, tiny) piece of Spring |
|
configuration that is required to actually <emphasis>'switch |
|
on'</emphasis> this behavior. Simply annotating the |
|
<emphasis>'setter'</emphasis> properties of your classes is not enough |
|
to get this behavior. You need to enable a component that is aware of |
|
the <interfacename>@Required</interfacename> annotation and that can |
|
process it appropriately.</para> |
|
|
|
<para>This component is the |
|
<classname>RequiredAnnotationBeanPostProcessor</classname> class. This |
|
is a special <interfacename>BeanPostProcessor</interfacename> |
|
implementation that is <interfacename>@Required</interfacename>-aware |
|
and actually provides the <emphasis>'blow up if this required property |
|
has not been set'</emphasis> logic. It is <emphasis>very</emphasis> easy |
|
to configure; simply drop the following bean definition into your Spring |
|
XML configuration.</para> |
|
|
|
<programlisting language="xml"><bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/></programlisting> |
|
|
|
<para>Finally, one can configure an instance of the |
|
<classname>RequiredAnnotationBeanPostProcessor</classname> class to look |
|
for <emphasis>another</emphasis> |
|
<interfacename>Annotation</interfacename> type. This is great if you |
|
already have your own <interfacename>@Required</interfacename>-style |
|
annotation. Simply plug it into the definition of a |
|
<classname>RequiredAnnotationBeanPostProcessor</classname> and you are |
|
good to go.</para> |
|
|
|
<para>By way of an example, let's suppose you (or your organization / |
|
team) have defined an attribute called @ |
|
<interfacename>Mandatory</interfacename>. You can make a |
|
<classname>RequiredAnnotationBeanPostProcessor</classname> instance |
|
<interfacename>@Mandatory</interfacename>-aware like so:</para> |
|
|
|
<programlisting language="xml"><bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"> |
|
<property name="requiredAnnotationType" value="your.company.package.Mandatory"/> |
|
</bean></programlisting> |
|
|
|
<para>Here is the source code for the |
|
<interfacename>@Mandatory</interfacename> annotation. You will need to |
|
ensure that your custom annotation type is itself annotated with |
|
appropriate annotations for its target and runtime retention |
|
policy.</para> |
|
|
|
<programlisting language="java">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 { |
|
}</programlisting> |
|
</section> |
|
|
|
<section id="metadata-annotations-other"> |
|
<title>Other @Annotations in Spring</title> |
|
|
|
<para>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.</para> |
|
|
|
<itemizedlist> |
|
<listitem> |
|
<para><xref linkend="transaction-declarative-annotations" /></para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><xref linkend="aop-atconfigurable" /></para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><xref linkend="aop-ataspectj" /></para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><xref linkend="beans-annotation-config" /></para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><xref linkend="beans-classpath-scanning" /></para> |
|
</listitem> |
|
</itemizedlist> |
|
</section> |
|
</section> |
|
</chapter>
|
|
|