Spring Konzepte und Annotationen

Das Spring Framework erlaubt die schnelle Umsetzung von robusten, leicht wartbaren Enterprise Applikationen basierend auf der Umsetzung zahlreicher Design Pattern sowie einem modularen Design.

Spring basiert insgesamt auf 20 Modulen aus den Bereichen Datenhaltung, Web, Aspect-oriented programming (AOP), Aspects, Instrumentation, Messaging, Testing sowie dem Core Container [4].

Ein wichtiges in Spring [3] umgesetztes Design Pattern ist Inversion of Control (IOC).

Objekte, die vom Spring IOC Container gemanagt (initialisiert, konfiguriert und zusammengestellt) werden, werden Beans genannt.

IOC wird, benannt nach Martin Fowler, auch Dependency Injection (DI) genannt. Hierbei definieren Objekte ihre Abhängigkeiten zu anderen Objekten, wobei der IOC Container diese zur Laufzeit mit Hilfe den gegebenen Konfigurationen und Metadaten auflöst.

DI führt zwangsweise zu übersichtlicherem Code und loser Kopplung zwischen Klassen. Im folgenden sind die wichtigsten Spring Boot Annotationen und kurze Erklärungen aufgeführt.

Dependency Injection

@Required wird für DI über Setter-Methoden für eine Bean Property angewandt die zwingend beim Startup (Configuration time) instantiiert werden müssen. Damit werden später auftretende NullPointerException abgewendet.

@AutoWired teilt Spring mit, wo es mittels Injection Objekte in andere Klassen einfügen soll. Die Injection erfolgt über den Typ des Objekts. Standardmäßig werden diese Abhängigkeiten als required angesehen, mittels @Autowired(required=false) kann man dieses Verhalten jedoch ausschalten. Pro Klasse kann nur ein Konstruktor required sein.

@Primary definiert eine Bean als priorisiert für den Autowire-Vorgang, wenn mehrere Kandidaten zur Verfügung stehen würden.

@Qualifier("name") erlaubt, den Autowire-Vorgang noch genauer zu spezifizieren. So kann man eine Bean mittels eines Qualifiernamens mit einem Konstruktorargument zusammenschalten. Der selbe Name darf mehrfach vergeben werden.

@Resource("beanName") kombiniert @AutoWired und @Qualifier(“beanName”). Die Injection erfolgt über den eindeutigen Namen. Es ist jedoch nur für Felder und Bean Setter-Methoden mit einem einzigen Argument anwendbar.

Klassen-/Methoden-Annotationen

@Repository für DAO (Data Access Object) Klassen. DAO stellt ein Pattern dar, dass auf einheitliche Weise den Zugriff auf Datenquellen kapselt (Datenbanken, XML-Files, etc.)

@Service markierte eine Klasse als Dienstklasse.

@Component ist ein generischer Stereotyp für eine Bean, also Klassen die weder Service noch Repository sind. Die Annotationen @Controller, @Service und @Repository stellen Spezialisierungen dieser Annotation dar.

@Configuration markiert eine Klasse als Konfigurationsklasse für Bean Definitionen. Dies bietet den Vorteil, dass Abhängigkeiten zwischen Beans definiert werden können. @ComponentScan erlaubt zusätzlich das automatische Auffinden von Beans. Des Weiteren können Init und Destroy-Methoden von Beans mittels @Bean(initMethod = “init”) und @Bean(destroyMethod = “destroy”) definiert werden. Mittels @Import und @ImportResource können weitere Konfigurationklassen geladen werden.

@Scope("name") definiert den Lebenszyklus einer Bean [2], u.a. singleton (es kann nur eine Instanz erzeugt werden), request (gültig für eine einzelne HTTP-Anfrage), session (gültig für eine HTTP-Session), prototype (Bean Definition wird auf eine beliebige Anzahl von Objektinstanzen angewandt). Es können ebenso die Klassenannotationen @RequestScope, @SessionScope, usw. genutzt, sowie eigene Scopes definiert werden. Der Defaultwert ist singleton, wobei die Bean erzeugt wird wenn der Container erzeugt wird (im Gegensatz zur Lazy-Initialisierung zum Zeitpunkt der ersten Nutzung). Singleton wird typischerweise für stateless, prototype für stateful Beans genutzt.

@Transactional annotiert Methoden oder Service-Klassen, die Geschäftslogik umsetzen.

@Bean("name") markiert eine Methode, die ein Bean-Objekt erzeugt, konfiguriert und initialisiert, die vom Spring IOC Container im ApplicationContext verwaltet werden soll. Der Container weiß somit wie die Bean erzeugt werden soll (lazy), welche Lifecycle-Constraints gelten (init, destroy) und wie deren Abhängigkeiten zu anderen Beans ist. @Bean wird typischerweise in @Configuration-Klassen genutzt. In anderen Klassen markiert sie einfache Factory-Methoden. Der Name der Bean ist identisch mit dem Klassenname, sofern nicht händisch ein oder mehrere andere Bezeichner gewählt werden. Besitzt eine Bean eine Methode names close() oder shutdown() werden diese automatisch beim beenden des Containers ausgeführt.

@PostConstruct und @PreDestroy erlauben eigenes Verhalten beim Erzeugen und Beenden einer Bean zu definieren.

@Order und @Priority um Elemente in einem Array oder Liste in einer bestimmten Weise zu sortieren.

Attribut-Annotationen

@Value("#{...}") markiert ein Attribut, eine Methode oder einen Konstruktor als Default.

Spring MVC Annotationen

@Controller markiert eine Klasse als Controller (bzw. Servlet). Diese Klasse wird automatisch nach @RequestMapping Annotationen durchsucht.

@RequestMapping(path="URL", method=RequestMethod.{GET|POST|PUT}) bildet URLs auf Klassen oder Methoden ab. Typischerweise bilden die Klassenannotationen auf einen Form-Controller ab. Seit Spring 4.3 sind auch kurze Varianten verfügbar: @GetMapping, @PostMapping, etc.

@PathVariable wird auf ein Methodenargument angewandt um den Wert einer URI Templatevariable auf das Attribut abzubilden.

Aufrufpfad: /customers/1

@RequestParam bildet Anfrageparameter auf Methodenvariablen ab.

Aufrufpfad: /customers/add?id=3&preName=A&surName=B (Case Sensitive!)

javax.inject.*

Dieses Paket bietet Dependency Injection für Java an.

@Inject kann anstelle von @Autowired für Attribute, Methoden und Konstruktoren verwendet werden. Um einem abhängigen Attribut einen Qualifier mitzugeben, verwendet man in diesem Fall @Named("...").

Weitere Annotationen dieses Pakets sind @ManagedBean, @Singleton und @Qualifier.

 

Natürlich ist diese Zusammenfassung nicht vollständig (@Lazy,  @Profile("development"/"production") , @PersistenceContext,  @PropertySource, etc.). Vielen Annotationen können zudem Parametrisierungen mitgegeben werden. Diese wurden hier der Übersichtlichkeit halber weitestgehend außer acht gelassen.

[1] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-annotation-config/

[2] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes

[3] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/index.html

[4] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/overview.html#overview-modules