Annotationen in Spring 2.0/2.5 für Autowire und neue Beans
Bis Spring 2.0 gab es im Wesentlichen nur eine Möglichkeit, Spring-Beans zu deklarieren und Bean-Referenzen zu injizieren. Ab Spring 2.0 und besonders in Spring 2.5 gibt es einen Richtungswechsel. Statt Bean-Definitionen und Injizierungsanweisungen ausschließlich über XML-Dokumente zu beschreiben, kommen Annotationen hinzu. Spring nutzt zum Einen Standard-Annotationen aus Java 6 (Common Annoations) aber auch eigene.
Nehmen wir zwei Beans an:
Die Bean CalendarPrinter soll ein Datum injiziert bekommen.
public class CalendarPrinter { public void setDate( Date date ) ...
Über XML lässt sich das einfach beschreiben, doch seit Spring 2.5 veranlasst eine Annotation Spring dazu, die Verweise automatisch zu injizieren:
@Autowired
@Autowired ist eine Annotation für Methoden und Attribute, damit Spring selbständig den Verweis setzt:
public class CalendarPrinter { @Autowired public void setDate(@Qualifier("today") Date d) ... }
Die Annotation @Qualifier ist nur dann nötig, wenn es mehrere Beans dieses Typs gibt. (Nicht bei uns.)
Damit Spring überhaupt die Verknüpfung vornimmt, ist in der XML-Datei ein Hinweis zu setzen.
Die erste Möglichkeit ist:
Eine im Allgemeinen bessere Alternative (die AutowiredAnnotationBeanPostProcessor und CommonAnnotationBeanPostProcessor zusammenfasst) ist
Die Annotation @Autowired ist genauso gültig bei Attributen:
public class CalendarPrinter { @Autowired Date date; public void doIt() { System.out.println( date ); } }
Java 6 (für Java 5 ist ein Extra-Jar nötig) führt aus JSR-250 die Lebenszyklus-Annotationen @PostConstruct und @PreDestroy sowie @Resource ein.
public class CalendarPrinter { @PostConstruct public void initialize() { System.out.println( "init" ); } /* @PreDestroy public void remove() { System.out.println( "destroy" ); } */ }
Beans deklarieren
Die Verknüpfung ist durch Autowire automatisiert und minimiert die XML-Konfigurationsdatei. Zum Deklarieren von neuen Beans bringt Spring ebenfalls Annotationen mit. Statt in der XML-Datei zu schreiben
können wir annotieren:
@Component class CalendarPrinter
Damit Spring nach annotierten Beans sucht, ist nötig:
Die Annotation @Component ist an allen Typen erlaubt und natürlich zur Laufzeit sichtbar:
@Target(value=TYPE) @Retention(value=RUNTIME) @Documented public @interface Component { String value(); }
API zur Eigenschaft: „The value may indicate a suggestion for a logical component name, to be turned into a Spring bean in case of an autodetected component.“
Geben wir dem CalendarPrinter den Bean-Namen „ cal-printer“:
@Component("cal-printer") public class CalendarPrinter
Aus dem ApplicationContext genommen folgt:
ApplicationContext context = new ClassPathXmlApplicationContext( ... ); Object bean = context.getBean( "cal-printer" ); System.out.println( bean.getClass() ); // class com.tutego.spring.annotation.CalendarPrinter
@Component ist eine sehr allgemeine Annotation.
Besser ist es, semantische Annotationen zu nutzen, die @Component erweitern. Spring liefert drei mit:
@Target(value=TYPE) …@Componentpublic @interface Repository@Target(value=TYPE) …@Componentpublic @interface Service@Target(value=TYPE) …@Componentpublic @interface Controller