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:

    <bean id="today" class="java.util.Date" /> 
<bean id="calendarPrinter"
class="com.tutego.spring.annotation.CalendarPrinter" />

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:

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

Eine im Allgemeinen bessere Alternative (die AutowiredAnnotationBeanPostProcessor und CommonAnnotationBeanPostProcessor zusammenfasst) ist

    <context:annotation-config/>

Die Annotation @Autowired ist genauso gültig bei Attributen:

    public class CalendarPrinter 
{
@Autowired Date date;

      public void doIt()
      {
        System.out.println( date );
      }
    }

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<bean id="today" class="java.util.Date" />
<bean id="calendarPrinter" class="com.tutego.spring.annotation.CalendarPrinter" />
</beans>

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

    <bean id="calendarPrinter" class="com.tutego.spring.annotation.CalendarPrinter" /> 

können wir annotieren:

    @Component class CalendarPrinter

Damit Spring nach annotierten Beans sucht, ist nötig:

    <context:component-scan base-package="com.tutego.spring" />

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:

  1. @Target(value=TYPE) … @Component
    public @interface Repository
  2. @Target(value=TYPE) … @Component
    public @interface Service
  3. @Target(value=TYPE) … @Component
    public @interface Controller

Über Christian Ullenboom

Ich bin Christian Ullenboom und Autor der Bücher ›Java ist auch eine Insel. Einführung, Ausbildung, Praxis‹ und ›Java SE 8 Standard-Bibliothek. Das Handbuch für Java-Entwickler‹. Seit 1997 berate ich Unternehmen im Einsatz von Java. Sun ernannte mich 2005 zum ›Java-Champion‹.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.