Enterprise OSGi: The Big Picture

Repository-Schicht mit Spring Data JPA

Ziel von Spring Data JPA [4] ist es, die Entwicklung der Repository-Schicht für JPA zu vereinfachen. Die gesamte Implementierung eines Repositories schrumpft zusammen auf ein Interface und die Spring-Konfiguration für Spring Data JPA. Realisieren wir nun also das AccountRepository mit Spring Data JPA. Dazu erstellen wir zunächst das Interface AccountJpaRepository als Erweiterung des Interfaces JpaRepository von Spring Data JPA. Im Interface AccountJpaRepository geben wir die Typisierung des Interfaces an. In unserem Fall verwaltet das Repository Instanzen der JPA Entity AccountImpl, die einen Primärschlüssel vom Typ Integer haben. Listing 2 zeigt den Typ des Interfaces sowie die save-Methode für die Konten.

Listing 2
public interface AccountJpaRepository extends JpaRepository {

   @Override
   AccountImpl save(AccountImpl account);
   
}

Um das Interface mit Leben zu füllen, folgt die Spring-Konfiguration in Listing 3.

Listing 3

Zur Laufzeit erzeugt Spring Data nun eine konkrete Instanz des Interface AccountJpaRepository und stellt sie als Spring Bean mit der ID accountJpaRepository zur Verfügung. Hinter den Kulissen sorgt Spring Data JPA für die konkrete Implementierung, die hinter dem Interface steht. Aber Moment mal! Wir wollten doch eine Implementierung des Interface AccountRepository, nicht AccountJpaRepository! Damit haben wir leider eine Schwachstelle von Data JPA identifiziert. Spring Data JPA benötigt immer die konkrete JPA Entity und ist nicht in der Lage, mit Interfaces umzugehen. Wir sind also gezwungen, eine Wrapper-Klasse AccountRepostoryImpl zu schreiben, die per Dependency Injection eine Instanz des AccountJpaRepository-Interfaces erhält und alle Operationen an dieses delegiert. Die Klasse AccountRepositoryImpl sorgt dafür, dass nur die Interfaces nach außen sichtbar sind.

Spring Data JPA Repositories unterstützen bereits von Haus aus Paging – Sortierung. Auch eigene Finder-Methoden wie findCustomerByName können ohne eine Zeile Code realisiert werden. Obendrauf gibt es auch noch Implementierungen von Spring Data für NoSQL-Datenbanken wie Mongo DB. Beim Wechsel auf Mongo DB können so große Teile des Codes und der Spring-Konfiguration wiederverwendet werden.

Logging

Aufgepasst, jetzt kommt ein Klassiker: Logging. Ach, Sie kennen das Problem? Ja richtig, dafür gibt es schon eine Lösung, nämlich Log4j. Oder Apache Commons Logging. Oder Java Utils Logging. Aktuell ist ja gerade Logback… Aber halt, wir nutzen doch OSGi! Also wie wäre es dann mit dem OSGi LogService?

Das Thema ist so komplex, dass Ekkehard Gentz in seinem Blog eine neunteilige (!) Serie darüber verfasst hat [5]. Fakt ist, dass unsere Enterprise-Anwendung in der Lage sein muss, mit verschiedenen Logging-Frameworks umzugehen. Dabei hilft uns SLF4J [6] mit seinen Bindings für diverse Logging-Frameworks. Als konkrete Implementierung des SLF4J API bietet sich Logback [7] an. Zu diesem Schluss ist auch Ekkehard Gentz gekommen – und der muss es ja wissen.

Auch für unseren Code ist das API von SLF4J eine gute Wahl. Denn damit sind wir unabhängig von einem Logging-Framework, und der Code lässt sich auch außerhalb der OSGi-Welt problemlos verwenden. Das habe ich auch für unser Beispielprojekt gemacht. Die Logback-Konfiguration liegt im Bundle com.pe-international.sample.logback. Das ist ein Fragment des Logback Bundles. So findet Logback die Konfigurationsdatei logback.xml über den Classpath. Alternativ könnten wir Logback auch über die System Property logback.configurationFile mitteilen, wo die Konfiguration zu finden ist.

Eine andere Möglichkeit fürs Logging wäre Pax Logging [8]. Pax Logging implementiert neben dem OSGi LogService auch die Schnittstellen von SLF4J, Log4j, Commons Logging und ein paar mehr. Als Backend unterstützt es derzeit nur Log4j, unter [9] ist jedoch auch eine Implementierung für Logback zu finden.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.