Vous êtes sur la page 1sur 11

JavaBean

Présentation de la « Technologie » JavaBean = langage Java


– pas de concept ou syntaxe nouveaux

technologie JavaBeans – pas de classe Bean ou de bibliothèque spéciale


– pas d'API pour les Bean

en mémoire de M. Jourdain seule contrainte précise :


bourgeois gentilhomme un bean doit avoir un constructeur sans arguments
qui faisait de la prose sans le savoir

www.dil.univ-mrs.fr/~garreta/I
Octobre 2005 JavaBeans 1 Octobre 2005 JavaBeans 3

JavaBean JavaBean
• Composant logiciel réutilisable pouvant être Mais, alors, de quoi allons-nous parler?
manipulé visuellement par un outil de développement
– modèles de conception
• règles pour nommer les méthodes publiques
palette de beans • des méthodes « obligatoires »

– réflexion
deux beans
• possibilité de découvrir à l'exécution les membres d'un objet
instanciés
– persistance
Inspecteur • sérialisation d’un bean : fichier binaire ou XML (long terme)
de propriétés • désérialisation d'un bean : alternative à la construction

Octobre 2005 JavaBeans 2 Octobre 2005 JavaBeans 4


JavaBean Événements
Exemple : doit posséder les méthodes
d'enregistrement d'auditeurs
add<quoi>Listener(<quoi>Listener x)
public class Entier implements Serializable {
remove<quoi>Listener(<quoi>Listener x)
private int valeur = 0; notifie un événement
Source d'événements
public int getValeur() { objet
return valeur; événement
}
public void setValeur(int v) {
est
valeur = v; Auditeur d'événements
} enregistré comme auditeur
} doit posséder les méthodes
de notification de l'événement
le constructeur d'un bean n'est pas très important implements <quoi>Listener

Octobre 2005 JavaBeans 5 Octobre 2005 JavaBeans 7

JavaBean Événements
• événement : instance d'une classe
Des éléments du langage Java particulièrement sollicités <C>Event ex: MouseEvent

– événements sous-classe de java.util.EventObject


• communication entre beans
deux manières
– propriétés d'attacher
un bean à un autre précise la source de l'événement
• variables « très » publiques
définissent état du bean et des informations complémentaires
exemple (événements awt-Swing) :
– sérialisation & archivage (x, y), temps, commande associée…
• mettre un bean (objet) dans un fichier (suite d'octets)
• outil jar, fichier manifeste, etc.

Octobre 2005 JavaBeans 6 Octobre 2005 JavaBeans 8


Événements Evénement « ma température a changé »
• événement : instance d'une classe public class TempChangeEvent extends EventObject {
<C>Event ex: MouseEvent protected double temp;
sous-classe de java.util.EventObject public TempChangeEvent(Object source, double temp){
super(source);
this.temp = temp;
• auditeur correspondant : ex: MouseListener }
implements <C>Listener public double getTemperature() {
sous-interface de java.util.EventListener return temp;
}
fixe la liste des méthodes par lesquelles }
l'événement est notifié :
public void mousePressed(MouseEvent evt); public interface
TempChangeListener extends EventListener {
public void mouseReleased(MouseEvent evt); void tempChange(TempChangeEvent evt);
etc. }

Octobre 2005 JavaBeans 9 Octobre 2005 JavaBeans 11

Événements Source d’événements TempChangeEvent


• événement : instance d'une classe public class PointChaud {
<C>Event ex: MouseEvent protected double tempCour = 18;
sous-classe de java.util.EventObject …
public double getTemperatureCourante() {
• auditeur correspondant : return tempCour;
ex: MouseListener }
implements <C>Listener
sous-interface de java.util.EventListener public void setTemperatureCourante(double temp) {
tempCour = temp;
notifyTemperatureChange();
• source de ce type d’événement : possède deux méthodes }
add<C>Listener(<C>Listener u) …
remove<C>Listener(<C>Listener u)
}
ex: addMouseListener(MouseListener u)
[ à suivre… ]

Octobre 2005 JavaBeans 10 Octobre 2005 JavaBeans 12


Source d’événements TempChangeEvent Source d’événements TempChangeEvent
[ …suite ] [ …suite ] Version habituelle

public class PointChaud { public class PointChaud {


… private Vector tempChangeListeners = new Vector();
private Vector tempChangeListeners = new Vector(); …
protected void notifyTemperatureChange() {
public synchronized void TempChangeEvent evt
addTempChangeListener(TempChangeListener l) { = new TempChangeEvent(this, tempCour);
if ( ! tempChangeListeners.contains(l))
tempChangeListeners.addElement(l); Vector v;
} synchronized(this) {
v = (Vector) tempChangeListeners.clone();
public synchronized void }
removeTempChangeListener(TempChangeListener l) {
if (tempChangeListeners.contains(l)) Iterator iter = v.iterator();
tempChangeListeners.removeElement(l); while (iter.hasNext())
} ((TempChangeListener) iter.next()).tempChange(evt);
… }

} [ à suivre… ] }
Octobre 2005 JavaBeans 13 Octobre 2005 JavaBeans 15

Source d’événements TempChangeEvent Auditeur d’événements TempChangeEvent


[ …suite ] Version simpliste
public class Thermostat implements TempChangeListener {
public class PointChaud {
private PointChaud pointChaud;
private Vector tempChangeListeners = new Vector();
… public void appliquerSur(PointChaud pointChaud) {
protected void notifyTemperatureChange() { this.pointChaud = pointChaud;
TempChangeEvent evt pointChaud.addTempChangeListener(this);
= new TempChangeEvent(this, tempCour); }
Iterator iter = tempChangeListeners.iterator(); public void tempChange(TempChangeEvent evt) {
while (iter.hasNext()) System.out.println("Nouvelle temperature : "
((TempChangeListener) iter.next()).tempChange(evt); + evt.getTemperature() + "° C");
} }
… ...
} }

Octobre 2005 JavaBeans 14 Octobre 2005 JavaBeans 16


Essai Assemblage dynamique des beans
public class Essai {
(les adaptateurs et la réflexion)
public static void main(String[] args) {
PointChaud point = new PointChaud(); Exemple : comment avoir un auditeur d’un événement qui réagit
Thermostat thermo = new Thermostat(); différemment selon la source ?
thermo.appliquerSur(point);
...
point.setTemperatureCourante(17); Thermostat thermo = new Thermostat();
point.setTemperatureCourante(16); ...
point.setTemperatureCourante(15); thermo.appliquerSur(point1, methode1);
... thermo.appliquerSur(point2, methode2);
} thermo.appliquerSur(point3, methode3);
... ...
}
et, surtout, comment l’avoir à l’exécution ?

Octobre 2005 JavaBeans 17 Octobre 2005 JavaBeans 19

Resumé Adaptateurs
code imposé dans une source d'événements Exemple : un auditeur et un événement, mais
plusieurs sources et plusieurs réactions possibles
liste des auditeurs :
Vector tempChangeListeners;
Auditeur ( un Thermostat )
gestion de cette liste : méthode 1 méthode 2 méthode 3
void addTempChangeListener(TempChangeListener l);
void removeTempChangeListener(TempChangeListener l);
Notification
notification aux auditeurs :
void notifyTemperatureChange();
Source 1 Source 2 Source 3
Les objets PropertyChangeSupport allègent ces corvées

première idée : écrire du code source spécifique


Octobre 2005 JavaBeans 18 Octobre 2005 JavaBeans 20
Démultiplexage La réflexion, un exemple
public class DemoReflexion {
Ecrire du code source : ...
public static void main(String[] args) {
public class Thermo2 implements TempChangeListener {
toutEssayer(new BigInteger("10000000000001"),
PointChaud point1, point2, point3;
new BigInteger("10000000000003"));
...
toutEssayer("bonjour", "BonJour");
public void tempChange(TempChangeEvent evt) {
}
if (evt.getSource() == point1)
}
methode1();
else if (evt.getSource() == point2)
methode2(); exécution
else 10000000000001.compareTo(10000000000003) = -1
methode3(); 10000000000001.add(10000000000003) = 20000000000004
} ...
10000000000001.remainder(10000000000003) = 10000000000001
...
bonjour.compareTo(BonJour) = 32
}
bonjour.compareToIgnoreCase(BonJour) = 0
...
C’est lourd et pas dynamique : pour chaque nouvelle source il faut recompiler bonjour.concat(BonJour) = bonjourBonJour

Octobre 2005 JavaBeans 21 Octobre 2005 JavaBeans 23

Adaptateurs La réflexion, un exemple


public class DemoReflexion {
Exemple : un auditeur et un événement, mais ...
plusieurs sources et plusieurs réactions possibles static void toutEssayer(Object a, Object b) {
try {
Class classe = a.getClass();
Auditeur ( un Thermostat ) Method[] methodes = classe.getMethods();
for (int i = 0; i < methodes.length; i++) {
Méthode 1 Méthode 2 Méthode 3 Method met = methodes[i];
Class[] params = met.getParameterTypes();
if (params.length == 1 &&
Adaptateur ( AdaptateurTemperature ) params[0].isAssignableFrom(b.getClass()))
System.out.println(a + "."
+ met.getName() + "(" + b + ") = "
+ met.invoke(a, new Object[] { b } ));
Source 1 Source 2 Source 3 }
} catch (Exception ex) {
ex.printStackTrace();
pour écrire l’adaptateur : la réflexion de Java }
} a.<met>(b)
}
Octobre 2005 JavaBeans 22 Octobre 2005 JavaBeans 24
Adaptateurs
Propriétés
public class Thermo3 {
protected AdaptaTemp adaptateur; Propriété
public Thermo3(PointChaud a, PointChaud b, PointChaud c) { public void set<nom>(<type> val);
... public <type> get<nom>();
adaptateur = new AdaptaTemp(this);
try { exemple
adaptateur.enregistrer(a, "changementTemp1");
adaptateur.enregistrer(b, "changementTemp2"); public void setTemperature(int val);
adaptateur.enregistrer(c, "changementTemp3"); public int getTemperature ();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} cible
...
}
void changementTemp1(TempChangeEvent evt) { ... }
void changementTemp2(TempChangeEvent evt) { ... }
void changementTemp3(TempChangeEvent evt) { ... }
}

Octobre 2005 JavaBeans 25 Octobre 2005 JavaBeans 27

Adaptateurs Propriétés
public class AdaptaTemp implements TempChangeListener {
Object cible;
Map repert = new HashMap();
Propriété
AdaptaTemp(Object cible) { public void set<nom>(<type> val);
this.cible = cible;
}
public <type> get<nom>();
void enregistrer(PointChaud source, String nomMethode) exemple
throws NoSuchMethodException {
Method methode = cible.getClass().getMethod( public void setTemperature(int val);
nomMethode, new Class[] { TempChangeEvent.class });
repert.put(source, methode); public int void getTemperature ();
source.addTempChangeListener(this);
} souvent il y a une variable derrière
public void tempChange(TempChangeEvent evt) { int tempCour;
try {
public void setTemperature(int val) {

re !
Method methode = (Method) repert.get(evt.getSource());
tempCour = val;

bl i s t
methode.invoke(cible, new Object[] { evt });

to i
s o n'e
} catch (Exception e) { }

ga
pa is ce
e.printStackTrace(); public int void getTemperature () {
} return tempCour;

ma
}
}
}

Octobre 2005 JavaBeans 26 Octobre 2005 JavaBeans 28


Propriétés Propriétés liées
• Aide pour les propriétés liées :
• Propriété booléenne
public class PropertyChangeSupport {
public void set<nom>(boolean val);
public PropertyChangeSupport(Object source);
public boolean is<nom>();
public synchronized void
addPropertyChangeListener(PropertyChangeListener l);
public synchronized void
• Propriété indicée removePropertyChangeListener(PropertyChangeListener l);
public void set<nom>(<type>[] val);
public void firePropertyChange(String propertyName,
public <type>[] get<nom>(); Object oldValue, Object newValue);
}
public void set<nom>(int i, <type> val);
public <type> get<nom>(int i);

prudence…
Octobre 2005 JavaBeans 29 Octobre 2005 JavaBeans 31

Propriétés liées Propriétés liées


public class PointChaud {
private double temperature = 18;
• Propriétés liées private PropertyChangeSupport aide;
public PointChaud() {
– des objets ont été enregistrés comme
aide = new PropertyChangeSupport(this);
devant être prévenus quand la valeur de la propriété change
}
– quand la valeur change l'objet notifie un événement public void addPropertyChangeListener(
propertyChangeEvent PropertyChangeListener l) {
aide.addPropertyChangeListener(l);
– avec : la source (possédant la propriété) }
le nom de la propriété public void setTemperature(double newTemp) {
l'ancienne et la nouvelle valeur
Double old = new Double(temperature);
temperature = newTemp;
Double new = new Double(temperature);
aide.firePropertyChange("temperature", old, new);
}
...
}
Octobre 2005 JavaBeans 30 Octobre 2005 JavaBeans 32
Propriétés contraintes Persistance
• pour en changer la valeur il faut le feu vert d’autres objets objet persistant
(enregistrés comme tels) • dont l'état est conservé entre deux exécutions du programme

• avant le changement, un événement vetoableChange leur est


notifié dit autrement, objet qui
• se laisse enregistrer dans un fichier
• si quelqu'un s'oppose au changement une exception • peut être ultérieurement recrée à partir de sa version sauvée
PropertyVetoException est lancée
plusieurs mécanismes
• les propriétés contraintes sont souvent liées aussi :
l'événement propertyChange est notifié après le changement • sérialisation de Java
• persistance à long terme : XML
• SGBD

Octobre 2005 JavaBeans 33 Octobre 2005 JavaBeans 35

Propriétés contraintes Sérialisation


...
void setTemperatureSouhaitee(double temp) { • ObjectOutputStream : conversion d’un objet Java
Double old = new Double(temperature); en un flot d’octets
Double new = new Double(temp);
...
try { • ObjectInputStream : conversion réciproque
aide1.fireVetoableChange("temperature", old, new);
}
catch (PropertyVetoException e) { le service rendu est considérable :
// quelqu'un s'oppose au changement • opération aussi complexe que le garbage collector
return; (les objets sont des graphes, souvent cycliques)
} • gestion de la cohérence de la classe
// OK, personne ne s’oppose au changement
lors de la sérialisation et la dé-sérialisation
temperature = temp;
aide2.firePropertyChange("temperature", old, new);
}
}
...

Octobre 2005 JavaBeans 34 Octobre 2005 JavaBeans 36


Sérialisation Sérialisation
class Maillon implements Serializable { class Maillon implements Serializable {
int val; ...
Maillon suiv; }
Maillon(int v, Maillon s) {
public class Degel {
val = v;
suiv = s; public static void main(String args[]) {
} Maillon liste = null;
} ...
try {
public class Congelation {
FileInputStream fichier = new FileInputStream("objet.fic");
public static void main(String args[]) {
ObjectInputStream entree = new ObjectInputStream(fichier);
Maillon liste, dernier = new Maillon(4, null);
liste = new Maillon(1, new Maillon(2, new Maillon(3, dernier))); liste = (Maillon) entree.readObject();
dernier.suiv = liste;
entree.close();
... }
dernier dernier
} catch (Exception e) {
} e.printStackTrace();
}
liste ... liste
}
1 2 3 4 } 1 2 3 4

Octobre 2005 JavaBeans 37 Octobre 2005 JavaBeans 39

Sérialisation Sérialisation explicite


class Maillon implements Serializable { class UneClasse implements Serializable {
...
} transient unType unMembre;
public class Congelation { ...
private void writeObject(ObjectOutputStream flux)
public static void main(String args[]) {
Maillon liste;
throws java.io.IOException {
... flux.defaultWriteObject();
try { ...
FileOutputStream fichier = new FileOutputStream("objet.fic"); comment écrire les membres transitoires
ObjectOutputStream sortie = new ObjectOutputStream(fichier); ...
sortie.writeObject(liste); }
sortie.close(); private void readObject(ObjectInputStream flux)
} throws java.io.IOException {
dernier
catch (IOException e) { flux.defaultReadObject();
e.printStackTrace();
...
}
... liste comment « lire » les membres transitoires
...
}
}
1 2 3 4 } méthodes magiques
... qu’il faut appeler
}

Octobre 2005 JavaBeans 38 Octobre 2005 JavaBeans 40


Sérialisation d’un bean Archives jar
class Confiture {
public static void main(String args[]) { Commande
Gadget unGadget = new Gadget();
… travail de personnalisation de unGadget …
jar {ctx}[vmf...]
<fichier manifeste> <fichier jar> sources...
try {
FileOutputStream fichier =
new FileOutputStream("Gadget.ser");
Exemple
ObjetOutputStream sortie = jar cvfm DixNiveaux.jar DixNiveaux.mf *.class
new ObjetOutputStream(fichier);
sortie.writeObject(unGadget);
sortie.close(); Fichier manifeste :
}
catch (Exception e) {
Name: MonGadget.class
System.out.println(e); Java-Bean: True
} ...
}
}

Octobre 2005 JavaBeans 41 Octobre 2005 JavaBeans 43

Dé-sérialisation d’un bean En guise de conclusion…

Remplace la construction des objets

s
ires
rce
...

bina
sou
JavaBeans :
try {
Gadget g = (Gadget)

composants
Beans.instantiate(null, "atelier.outils.MonGadget");

développement
}

logiciels
catch (Exception e) {
}
...
réutilisables
chargeur de classes Fichier
exécution
atelier/outils/MonGadget.ser

Octobre 2005 JavaBeans 42 Octobre 2005 JavaBeans 44