zum Inhalt

2 Das JavaBean-Modell

2.1 Grundlegendes

Die grundsätzlichen Merkmale des JavaBeans-Komponentenmodells und damit auch einzelner Java-Beans sind:

  • Introspection (dt. Selbstbeobachtung): erlaubt Builder-Tools, eine Bean zu analysieren und seine Fähigkeiten abzufragen.
  • Customization (dt. Anpassung): ermöglicht vor allem dem Entwickler, die Eigenschaften einer Bean visuell und interaktiv anzupassen.
  • Events (dt. Ereignisse): damit senden Beans Informationen über Zustandsänderungen und Benutzeraktivitäten an andere Beans und Builder-Tools.
  • Properties (dt. Eigenschaften): kapseln Instanzdaten einer Bean und können von außen abgefragt und manipuliert werden.
  • Persistenz (dt. Speicherung): ermöglicht es Builder-Tools, den angepaßten Zustand einer Bean dauerhaft zu speichern und wiederherzustellen.

    Die Properties sind den gekapselten Daten von Klassen vergleichbar. Eine von vielen weiteren Standard-Properties visueller Beans ist z. B. ihre Hintergrundfarbe. Durch die Zuweisung eines neuen Wertes aus einem Programm oder innerhalb eines interaktiven Code-Generators übernimmt die Bean die übergebene Einstellung und zeigt sie sofort an. Mittels Events tauschen verschiedene Beans und Anwendungen diverse vordefinierte und selbstprogrammierbare Informationen und Zustandsänderungen aus. Sie benutzen dabei intensiv das flexible Ereignismodell des JDK1.1, um so dynamisch und zur Laufzeit den Ereignisfluß zu steuern. Die Methoden von Beans enthalten schließlich den auszuführenden Funktionscode. Der Entwickler eines Beans hat dabei alle von Java bekannten Möglichkeiten, die Sichtbarkeit, sprich Aufrufbarkeit von außen, frei zu bestimmen. Der spätere Benutzer kann ausschließlich veröffentlichte Methoden einer Bean direkt aufrufen. Alles, was der Entwickler gekapselt hat, bleibt dem Nutzer verborgen. Über die optionale BeanInfo-Klasse ist es darüber hinaus möglich, noch gezielter auf das "äußere Erscheinungsbild" einer Bean Einfluß zu nehmen. So ist es in der Praxis möglich, fast jede vorhandene Java-Klasse per externer Anpassungsdeklaration, zu einer Bean werden zu lassen, ohne sie dafür neu übersetzen zu müssen.
    Da die Sprache Java nicht durch neue Schlüsselwörter erweitert werden sollte, ersann man ein einfaches und zugleich sehr leistungsfähiges Konzept für die Festlegung dessen, was eine Bean ausmacht: Entwurfsmuster für Funktionsnamen und Datentypen legen die Zusammengehörigkeit für bestimmte Aufgaben einer Bean fest.




    2.2 Introspection - gläserne Bohnen

    Der Introspection-Mechanismus erlaubt es anderen Komponenten oder dem Container, in dem sich die Komponente befindet, Einblick in den inneren Aufbau einer Komponente zu erhalten. Dies ist besonders dann sinnvoll, wenn die Komponenten in einem visuellen Editor zusammengesetzt werden. Der Anwender braucht sich dann nicht mehr durch die Dokumentation der jeweiligen Komponente zu wälzen, sondern die Entwicklungsumgebung kann selber herausfinden, welche Eigenschaften, Ereignisse und Methoden die Komponente zur Verfügung stellt. Falls dies nicht der Fall sein sollte, ist es immer noch möglich, über das Core-Reflection-API direkt in die Beans-Komponente hineinzuschauen und Informationen über die Klassen, Methoden und sogar einzelne Variablen zu erhalten.
    Auf diese Weise ist es für die Umgebung der Komponente immer möglich, zur Laufzeit Informationen über die Java-Bean zu erfragen. Umgekehrt kann auch eine Bean Informationen über ihre Umgebung beziehen. "Bohnen" können z. B. herausfinden, in welcher Umgebung sie sich befinden und ob sie sich gerade im Entwicklungsstadium in einem Visual Builder befinden oder ob sie sich in einem laufenden Programm befinden, oder ob sie auf dem User-Interface beispielsweise als Push-Button auftauchen. Die Bean kann durch Flags festlegen, ob es ein User-Interface benötigt, wie dies z. B. an einem Server ohne Monitor der Fall sein kann. Die Bean würde in diesem Fall signalisieren, daß sie einen Bildschirm benötigt und wird somit nur auf der Clientseite ausgeführt.

    Bean-Events
    public class java.util.EventObject extends java.lang.Object implements java.io.Serializable { 
    	protected transient Object Source;
    
    	public EventObject(Object source) { }
    	public Object getSource() { }
    	public String toString() { }
    }
    
    java.util.EventObject
    	java.awt.AWTEvent
    		java.awt.event.ActionEvent
    		java.awt.event.AdjustmentEvent
    		java.awt.event.ComponentEvent
    		java.awt.event.ContainerEvent
    		java.awt.event.FocusEvent
    		java.awt.event.InputEvent
    		java.awt.event.KeyEvent
    		java.awt.event.MouseEvent
    		java.awt.event.PaintEvent
    		java.awt.event.WindowEvent
    		java.awt.event.ItemEvent
    		java.awt.event.TextEvent
    	sunw.util.EventObject
    	java.beans.PropertyChangeEvent
     Abb. 2.2: JavaBean-Events




    2.3 Properties und Events...

    ...sind die wichtigsten Elemente einer Komponente. Properties dienen in erster Linie dazu, einer Bean interaktiv zur Laufzeit Parameter zu übergeben. Da sie aber als übliche Methoden implementiert sind, haben Entwickler zusätzliche Möglichkeiten für die Auswertung. Innerhalb der schreibenden set-Methode können der neue und alte Wert vor einer Änderung zuerst geprüft oder andere Aktionen gestartet werden. Bei den Properties wird zwischen Indexed-, Bound-, und Constraint-Properties unterschieden.
    Normale Properties repräsentieren einen einzelnen Wert, während Indexed-Properties ein Feld von mehreren gleichen Datentypen verwalten können. Für eine solche Property kommen je eine get/set-Methode mit einem int-Parameter als Index in das Datenfeld hinzu:
        public setIntFeld(int index, int wert);
        public getIntFeld(int index);
    Die Bound-Properties einer Bean kombinieren die Verwaltung von Properties mit dem Event-Mechanismus. Wo es angebracht ist, informieren Beans z. B. bei der Änderung einer ihrer Properties andere interessierte Komponenten, indem sie einen "PropertyChange-Event" auslösen. Die registrierten Beans empfangen den Event und können passend auf die Änderung reagieren.
    Noch einen Schritt weiter gehen schließlich die Constraint-Properties. Sie ermöglichen es, eine beabsichtigte Wertänderung von einer anderen Komponente prüfen zu lassen. Nur wenn keine externe Komponente ein "Veto" einlegt, darf die Änderung im Bean erfolgen.
    JavaBeans kommunizieren über Events miteinander. Die Klasse dient als Basisklasse für die versendeten Events. Die Implemetation benutzt dabei das JDK1.1-Ereignismodell mit seinen Event-Sources (Auslöser eines Ereignisses) und Event-Listenern (Empfänger für ein bestimmtes Ereigniss).




    2.4 Persistenz durch Serialisierbarkeit

    Ein wichtiger Mechanismus, der in der JavaBeans-Spezifikation festgelegt ist, ist die Persistenz einer Komponente [5] [5].
    Dies bedeutet, daß eine Komponente ihren Inhalt durch Serialisierung persistent ("dauerhaft") speichern kann. Zum Inhalt der Komponente gehören unter anderem die Properties und die übrigen durch die Komponente repräsentierten Daten, wie beispielsweise Biddaten oder Audiodateien. Durch die Serialisierung von Komponenten wird eine einheitliche Schnittstelle festgelegt, wodurch Komponenten ihren Inhalt beispielsweise auf der Festplatte abspeichern können.
    Die Daten werden hierbei durch spezielle API-Klasssen gesammelt und an Streams weitergegeben. Die Serialisierungs-Spezifikation von Java-Beans gewährleistet, daß der Inhalt einer Komponente nach einem einheitlichen Verfahren abgespeichert wird und somit zu einem späteren Zeitpunkt wieder geladen werden kann.
    Dies macht es möglich, daß der Zustand einer Komponente jederzeit wieder hergestellt werden kann und somit der Inhalt in gewisser Weise persistent bleibt.
    Über den Externalisierungs-Mechanismus erhält der Entwickler Eingriff in das Format der Datenabspeicherung einer Komponente und kann damit erreichen, daß die Daten der Bean-Komponente in einem bestimmten, von anderen Komponenten oder Programmen lesbaren Dateiformat wird. Auf diese Weise ist es auch möglich, eine Kompatibilität zu den Serialisierungsmechanismen von OpenDoc und OLE herzustellen, die zur Datenspeicherung das sogenannte "Bento-" bzw. "Structured-Storage"-Format verwenden.




    2.5 Die JavaBeans-"Design Patterns"

    Das Modell schreibt viele verschiedene "Name Patterns" [6] [6] vor. Hier sind nur die wichtigsten Vereinbarungen aus den Bereichen Properties und Events aufgelistet [7] [7]:

    Simple properties:
         public <PropertyType> getXXX();
         public void setXXX(<PropertyType> wert);
    bei einfachen Bool'schen Eigenschaften auch:
         public boolean isXXX();
         public void setXXX(boolean wert);


    Indexed-, Bound-, Constrained properties:
         public <PropertyType>[] getXXX();
         public void setXXX(<PropertyType>[] werte);
    oder:
         public <PropertyType> getXXX(int index);
         public void setXXX(int index, <PropertyType>[] wert);



    Falls eine Bean als Event-Source auftritt, gelten folgende Vereinbarungen:

    Multicast Events:
         public void add <EventListenerType> (EventListenerType a);
         public void remove <EventListenerType> (EventListenerType a);


    Unicast Events:
         public void add <EventListenerType> (EventListenerType a)
                          throws java.util.TooManyListenersException;
         public void remove <EventListenerType> (EventListenerType a);



    Eine detaillierte Beschreibung dieser (oder aller Vereinbarungen) ist im Umfang des Referates nicht möglich. In Kapitel 4 wird an einem einfachen Codebeispiel die Verwendung der Vereinbarungen demonstriert.




    2.6 Die Package java.beans.* (JDK1.1)

    Wie bereits weiter oben erwähnt, sind keine weiteren Schlüsselwörter notwendig um volle Bean-Funktionalität zu erhalten. Es war aber notwendig, den JDK um eine Package:
         java.beans.*
    zu erweitern, um die Bean-spezifischen Interfaces, Klassen und Exceptions zur Verfügung zu stellen. Die folgende Tabelle listet diese neuen Deklarationen jeweils mit einer kurzen Beschreibung auf:

    Klasse: Beschreibung:
    Interfaces  
    BeanInfo Allgemeine Schnittstelle für die Beschreibung eines Beans; üblich ist auch die Ableitung von SimpleBeanInfo
    Customizer Customizer sind graphische Assistenten für die aufgabenbezogene Einstellung von Eigenschaften eines Beans
    PropertyChangeListener Listener-Interfacefür Events, die über die Änderungen einer Property informieren (PropertyChangeEvent)
    PropertyEditor Schnittstelle für einfache Eingabemöglichkeiten zur Manipulierung einer Property in einem Property-Fenster
    VetoableChangeListener Listener für beabsichtigte Property-Änderungen (constrained); der Listener empfängt VetoableChangeEvents und kann eine Property-Änderung erlauben oder verbreiten.
    Visibility Interface für Beans, die eine graphische Oberfläche besitzen; reine Funktions-Beans benötigen kein GUI!
       
    Klassen  
    BeanDescriptor Ein BeanDescriptor stellt allgemeine Informationen über einen Bean öffentlich bereit, z. B. den Java-Klassenname oder den angezeigten Namen in Builder-Tools
    Beans Methoden für die Instanzierung und die Behandlung des Design-Modus in Builder-Tools
    EventSetDescriptor Beschreibt eine Gruppe von Events, die ein Bean auslösen kann
    FeatureDescriptor Super-Klasse für die anderen Descriptor-Klassen, stellt Informationen für die Introspektion bereit
    IndexedPropertyDescriptor Beschreibt indizierte Properties
    Introspector Stellt wichtige Methoden für die Introspection von Objekten zur Verfügung
    MethodDescriptor Beschreibt die Methoden einer Bean
    ParameterDescriptor Beschreibt die Parameter einer Bean
    PropertyChangeEvent Beans können diesen Event-Typ an registrierte PropertyChangeListener senden, um über die Änderung einer Property zu informieren
    PropertyChangeSupport Hilfsklasse für die Verwaltung von Änderungen bei Bound-Properties
    PropertyDescriptor Beschreibt eine Property und das zugehörige Paar von Lese- & Schreibfunktionen
    PropertyEditorManager Verwaltet die unterschiedlichen Property-Editoren
    SimpleBeanInfo Hilfsklasse mit einer einfachen Implementation des Interfaces BeanInfo
    VetoableChangeSupport Hilfsklasse für die Verwaltung von Änderungen bei constrained-Properties
       
    Exceptions  
    IntrospectionException Tritt bei Fehlern während der Introspection einer Bean auf
    PropertyVetoException Mit dieser Exception kann ein PropertyChangeListener die beabsichtigte Änderung einer Property verbieten
     Abb. 2.6: Die java.beans.* Package; Quelle: Java-Magazin 1/98 [8] [8]

    zu Kapitel 3 Kapitelanfang zum Inhalt