Einführung
Diese Richtlinie konzentriert sich auf das Design von EJBs. Weitere Anleitungen zu EJBs, z. B. zum Festlegen und
Modellieren von EJBs, finden Sie unter Richtlinie: EJBs.
Spezielle Anleitungen für das Design spezieller EJB-Typen finden Sie in folgenden Richtlinien:
Eine Beschreibung lokaler und ferner Schnittstellen finden Sie unter Konzept: Überblick über J2EE: Enterprise JavaBeans.
Lokale Schnittstellen sind effizienter als ferne Schnittstellen. Lokale Schnittstellen sollten dann verfügbar sein,
wenn spezielle Clients existieren, die für die EJB immer lokal sind.
Genauere Anleitungen zu diesem Thema finden Sie in den Richtlinien zu den speziellen Arten von EJBs.
Parameterübergabe
Die Leistung kann durch die Anzahl der Fernaufrufe und die Menge der bei jedem Aufruf übertragenen Daten stark
beeinträchtigt werden. Sie können dieses Problem umgehen, indem Sie bestimmte Aufrufe bereitstellen, die alle Daten
zurückgeben, die der ferne Client benötigt. Beispielsweise kann eine Session-Bean, die als Fassade für eine Gruppe von
zusammengehörigen Entity-Beans fungiert, die Daten aus mehreren Entity-Beans in serialisierbare Wertobjekte kopieren
und kann diese Daten in einem einzigen Fernaufruf zurückgeben. Eine detaillierte Beschreibung hierzu finden Sie unter
Core J2EE Patterns - Value Object Pattern ([ALU01]).
Diese Vorgehensweise muss von der Überlegung geleitet werden, die Schnittstellen so allgemein wie möglich zu halten und
das Senden von zu vielen überflüssigen Daten zu vermeiden.
Die Demarkation von Transaktionen bezeichnet das Einleiten, Festschreiben und Abbrechen von Transaktionen. Ein
EJB-Entwickler muss festlegen, ob eine Bean-gesteuerte Transaktion oder eine containergesteuerte Transaktion
implementiert werden soll. Sie selbst müssen die Positionen der Transaktionsgrenzen in der von der Anwendung
ausgeführten Geschäftslogik festlegen. Nähere Informationen hierzu finden Sie unter Aufgabe: Anwendungsfalldesign, Transaktionen modellieren und im
Abschnitt Transaktionsverwaltung in Konzept: Überblick über J2EE.
Verwenden Sie, wenn möglich, containergesteuerte Transaktionen. Sie können dann einen einfachen Code verwenden und die
Entwickler können sich auf die Geschäftslogik der Anwendung konzentrieren.
Im allgemeinen bewirken differenziertere Transaktionen eine bessere Gesamtleistung. Angenommen, Sie setzen eine Reihe
von Methodenaufrufen an die EJB ab (z. B. getX, getY und setZ). Standardmäßig wird jede Methode in einer neuen
Transaktion ausgeführt, was zu einer verminderten Leistung führt. Damit Sie diese Methoden innerhalb derselben
Transaktion aufrufen können, müssen Sie eine andere Methode erstellen, z. B. die Methode processXYZ einer Session-EJB,
und die Transaktionsattribute der aufgerufenen Methoden auf Required setzen, damit sie die vorhandene
Transaktion (d. h. die Transaktion der aufrufenden Methode in der Session-Bean) verwenden.
Grundlegende EJB-Sicherheitskonzepte werden in Konzept: Überblick über J2EE - Sicherheit erläutert.
Sie definieren die Sicherheitsanforderungen der EJBs, indem Sie Sicherheitsrollen und
Methodenberechtigungen festlegen. Sicherheitsrollen und Methodenberechtigungen werden im
Implementierungsdeskriptor der EJB definiert. Es ist Aufgabe des Servers, die Sicherheitsrollen (mittels
Verwaltungstools) den Benutzern oder Benutzergruppen zuzuordnen.
Eine Sicherheitsrolle definiert eine Gruppe von ähnlichen Aktivitätstypen, die unter einem einzigen Namen gruppiert
sind. Eine Methodenberechtigung erteilt einer bestimmten Sicherheitsrolle die Berechtigung zum Aufruf der Methode.
Beispiel: Angenomen, es existiert eine Entity-EJB mit dem Namen Employee mit den Methoden setAddress,
setSalary usw. Einer Sicherheitsrolle mit dem Namen manager könnten Methodenberechtigungen für die
Methoden setAddress und setSalary erteilt werden, während der Sicherheitsrolle mit dem Namen employee nur die
Methodenberechtigung für die Methode setAddress erteilt werden könnte.
In manchen Situationen ist es unmöglich, die Sicherheitsanforderungen einer Anwendung mit Hilfe von deklarativen
Methodenberechtigungen im Implementierungsdeskriptor zu erfüllen. In diesem Fall sollten Sie die Methoden
getCallerPrincipal und isCallerInRole der Schnittstelle javax.ejb.EJBContext verwenden.
Beginnend mit J2EE 1.4 (genauer mit EJB 2.1) können Stateless-Session-Beans und nachrichtengesteuerte Beans Zeitgeber
verwenden, um den zeitlichen Ablauf von Stapelprozessen über den EJB Timer Service zu planen.
Der EJB Timer Service stellt Methoden bereit, damit Callbacks für zeitabhängige Ereignisse geplant werden können. Der
Container stellt einen zuverlässigen, transaktionsorientierten Benachrichtigungsservice für zeitlich gesteuerte
Ereignisse bereit. Die Benachrichtigungen des EJB Timer Service können so geplant werden, dass sie zu einem konkreten
Zeitpunkt, nach Ablauf einer bestimmten Zeit oder in bestimmten sich wiederholenden Intervallen erfolgen.
Der Timer Service wird vom EJB-Container implementiert, und eine Enterprise-Bean kann über die Schnittstelle EJBContext
auf diesen Service zugreifen.
Der EJB Timer Service ist ein allgemein definierter Benachrichtigungsservice, der zur Verwendung bei der Modellierung
von Prozessen auf Anwendungsebene vorgesehen ist und nicht für die Modellierung von Echtzeitereignissen.
Direktzugriff vs. Entity-Beans
Die Verwendung von Entity-Beans für persistente Daten bietet einen mit vielen Funktionen ausgestatteten
Standardmechanismus für den Zugriff auf persistente Daten. Die Festlegung, ob eine über JavaBeans realisierte
Transaktionspersistenz oder eine über Container realisierte Transaktionspersistenz verwendet wird, kann gegenüber den
Clients verborgen werden, so dass das Design eine gewisse Flexibilität erhält. EJBs können Transaktionen, das
Ressourcenmanagement, den Lastausgleich und andere von der J2EE-Umgebung bereitgestellte Features nutzen.
Es können jedoch Situationen eintreten, in denen Sie direkt, ohne Verwendung von Entity-Beans, auf die Datenbank
zugreifen möchten. Wenn beispielsweise ein einzelner Client immer mit Lesezugriff auf die Daten zugreift, dann wäre der
direkte Zugriff auf die Datenbank effizienter.
Wenn Sie direkt auf die Datenbank zugreifen (z. B. über eine Stateless-Session-Bean), dann sollte der Datenbankzugriff
in eine DAO-Klasse (Data Access Object) eingebunden werden. Dies ist lediglich eine Java-Klasse, die das zugrunde
liegenden Speicherverfahren verbirgt und kapselt und die Änderungen isoliert, wenn sich die Schnittstelle zur
Datenquelle ändert. Siehe hierzu Core J2EE Patterns - Data Access Object Pattern ([ALU01]).
Praktisch alle EJB-Container unterstützen die Bündelung von Verbindungen in Verbindungspools, in denen eine Menge von
bereits erstellten Verbindungen von mehreren Clients gemeinsam verwendet wird. Diese Verbindungen werden den EJBs bei
Bedarf zugeordnet. Die EJB profitiert davon, weil sie eine Verbindung erhält, ohne dass sie diese erstellen und
initialisieren muss. Wenn die Verbindung an den Pool zurückgegeben wird, wird sie erneut gestartet. Im Pool sollten
genügend Verbindungen zur Verwendung bereit sein, damit die genutzten Verbindungen erneut gestartet werden können.
Für Entity-Beans mit über Container realisierter Transaktionspersistenz verwaltet der Container die Datenbankverbindung
und den Zugriff auf den Datenbankverbindungspool.
Für Entity-Beans mit über JavaBeans realisierter Transaktionspersistenz oder für Session- oder nachrichtengesteuerte
EJBs, die auf eine Datenbank zugreifen), ist der Entwickler zuständig für das Codieren der Verbindungsroutine. Es
gelten folgende Richtlinien:
-
Der Datenbankzugriffscode muss in einer DAO-Klasse isoliert werden.
-
Der tatsächliche URL der Datenbank darf nicht fest codiert werden. Statt dessen muss ein logischer Name verwendet
werden, der mittels einer JNDI-Suche (Java Naming and Directory Interface) abgerufen werden kann. Auf diese Weise
ist es möglich, die EJB in mehreren Anwendungen mit eventuell unterschiedlichen Datenbanknamen wiederzuverwenden.
-
Allgemein gilt, dass Verbindungspools verwendet werden sollten und dass die Verbindung nur so lange wie nötig
gehalten werden sollte. Beispielsweise kann eine Entity-Bean eine Verbindung aufbauen, eine Zeile in einer Tabelle
aktualisieren, und die Verbindung anschließend trennen. Auf diese Weise kann dieselbe Verbindung von vielen EJBs
gemeinsam genutzt werden. Die JDBC-Spezifikation beinhaltet auch die Unterstützung von Verbindungspools.
|