Framework Spring/Les beans

Un bean en Java est une convention d'interfaçage entre objets pour accéder à leur propriétés. Cette convention est utilisée dans les bibliothèques d'interfaces graphiques de Java (AWT, Swing, JavaFX), les outils de création d'interface et les frameworks Java. Pour une propriété simple nommée exemple de type type, la classe doit posséder certaines méthodes :

public type getExemple()
Méthode de lecture de la propriété (getter),
public boolean isExemple()
Méthode de lecture de la propriété quand elle est de type booléen,
public void setExemple(type value)
Méthode d'écriture de la propriété (setter), méthode absente si la propriété ne peut être écrite (lecture seule).

Pour une propriété de composition (liste de valeurs) :

public void addExemple(type item)
Méthode d'ajout d'un item,
public void removeExemple(type item)
Méthode de retrait d'un item.

Afin de pouvoir sérialiser les objets, la classe doit également posséder un constructeur par défaut (sans arguments) public et implémenter l'interface Serializable.

Interaction entre deux beans modifier

Les beans sont les enveloppes des classes configurées par Spring et permettent ainsi une interaction entre eux. Dans l'exemple Hello world! on avait un seul bean :

 <bean class = "mainPackage.MessageDisplayer">
  <property name = "message" value = "Hello world!"/>
 </bean>

Pour interagir avec le classe MessageDisplayer on crée la classe MessageDisplayerInserter :

 package mainPackage;
 public class MessageDisplayerInserter 
 {
  private int i;
 }

Pour l'instant on met un simple entier sans accesseurs. Dans le fichier bean.xml on ajoute un nouveau bean pour configurer la classe MessageDisplayerInserter :

 <bean class = "mainPackage.MessageDisplayerInserter">
  <property name = "i" value = "42"/>
 </bean>

En faisant cela on a le message d'erreur : " - No setter found for property 'i' in class 'mainPackage.MessageDisplayerInserter'". Cela provient du fait que Spring a besoin d'accesseurs pour les variables qui doivent être initialisées, même en les mettant en public. On obtient alors la classe suivante :

 package mainPackage;
 public class MessageDisplayerInserter {
 public int i;
 public int getI()
 {
  return i;
 }
 public void setI(int i) 
 {
  this.i = i;
 }
}

Pour faire l'insertion d'un bean dans l'autre on modifie le fichier Beans.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean class = "mainPackage.MessageDisplayer">
  <property name = "message" value = "Hello world!"/>
  <property name = "messageDisplayerInserter" ref = "mainPackage.MessageDisplayerInserter"/>
 </bean>
  <bean  class = "mainPackage.MessageDisplayerInserter">
   <property name = "i" value = "42"/>
  </bean>   
</beans>

Ici on met la valeur 42 pour i dans MessageDisplayerInserter et on insère cette classe dans la classe MessageDisplayer. On se sert du mot clé ref ici avec l'identifiant par défaut qui est le nom du package suivi du nom de la classe.

Ensuite il faut que la classe MessageDisplayer puisse implémenter MessageDisplayerInserter. On ajoute donc une variable de ce type avec le getter et setter pour que Spring puisse y accéder.

package mainPackage;
public class MessageDisplayer 
{
 private String message;
 private MessageDisplayerInserter messageDisplayerInserter;
 public void setMessage(String message)
 {
  this.message  = message;
 }
 public void displayMessage()
 {
  System.out.println("message : " + message+" messageDisplayerInserter.getI() : "+messageDisplayerInserter.getI());
 }
 public MessageDisplayerInserter getMessageDisplayerInserter()
 {
  return messageDisplayerInserter;
 }
 public void setMessageDisplayerInserter(MessageDisplayerInserter messageDisplayerInserter) 
 {
  this.messageDisplayerInserter = messageDisplayerInserter;
 }
}

En résultat on obtient cet affichage :

 

On a bien le résultat 42 affiché depuis la classe MessageDisplayer alors qu'il a été initialisé dans MessageDisplayerInserter.

Identification d'un bean modifier

Un bean peut être identifié avec l'attribut name et/ou l'attribut id. La différence est que name peut servir d'alias, on peut mettre plusieurs alias dans name alors que l'id doit être unique. Dans ce cas on peut modifier bean.xml de la manière suivante :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean class = "mainPackage.MessageDisplayer">
  <property name = "message" value = "Hello world!"/>
  <property name = "messageDisplayerInserter" ref = "MessageDisplayerInserter"/>
 </bean>
 <bean id="MessageDisplayerInserter" name="alias1,alias2" class = "mainPackage.MessageDisplayerInserter">
  <property name = "i" value = "42"/>
 </bean>   
</beans>

Le bean pour la classe MessageDisplayerInserter est maintenant identifié par son nom de classe sans avoir besoin d'ajouter le package. On peut aussi s'y référer via alias1 ou alias2.

Paramétrage via constructeur modifier

Dans le paramétrage des beans, au lieu d'insérer dans un attribut de la classe on peut faire appel au constructeur. On a alors le main de la forme suivante :

 package mainPackage;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 public class MainClass 
 {
  public static void main(String[] args) 
  {
   ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("Beans.xml");
   MessageDisplayer messageDisplayer = (MessageDisplayer) classPathXmlApplicationContext.getBean("mainPackage.MessageDisplayer");
   messageDisplayer.displayMessage();
   classPathXmlApplicationContext.close();
  }
 }

Le fichier Bean.xml a la forme suivante :

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean class = "mainPackage.MessageDisplayer"> 
   <constructor-arg value="42"/> 
  </bean> 
 </beans>

Les paramètres vont être lus dans l'ordre qui sont indiqués dans le bean. Si besoin est, on peut indiquer index dans le bean.