Vous êtes sur la page 1sur 32

EJB3

Entreprises Java Bean


Des composants qui s’intéressent plus particulièrement à la
logique métiers.
Ils servent d’intermédiaire entre les applications et la base de
données.
EJB 3 vs EJB 2
 les descripteurs de déploiement ne sont plus obligatoires grâce à l'utilisation
d'annotations et de valeurs par défaut

 Les EJB sont de simples POJO annotés : ils n'ont plus besoin d'implémenter une
interface de l'API EJB. De fait, il n'est plus nécessaire de définir des méthodes
liées au cycle de vie de l'EJB. Si ces méthodes sont nécessaires, il suffit d'utiliser
des annotations dédiées sur une méthode.

 Le type de l'interface de l'EJB est précisé avec l'annotation @Local ou @Remote


(use remote interfaces if the client are not in the same JVM)

 L'interface métier est une simple POJI

 Les EJB de type Entity utilise un modèle de persistance reposant sur l'API JPA
(Java Persistence API)

 Attention au convention de nommage.


Quelques généralités (1/2)

Un objet distribué


Déployé sur un serveur
Accessible à distance par de multiples utilisateurs
Un objet constitué
D’interfaces
D’un comportement métiers (fonctionnalités)

Conteneur:
Contexte d’exécution
Point d’entrée
Interfaces Composant Interfaces :
Cahier de charge du code métier

Base de données:
Objets Persistants
Quelques généralités (2/2)
Le client d’un EJB peut être :
Une servlet
Une application classique
Un autre bean
…

Normes et Historique
 EJB 1 : 1998
Première spécification « légère »
Seule le session bean
 EJB 2 : 2000
Amélioration des performances grâce à l’ajout des interfaces
Ajout des beans entité et MDB
 EJB 3 : 2006
Amélioration des performances
Simplification du développement
 Basé sur les annotations java
Taxonomie des Beans

Réalise des actions


de manière
asynchrone
Un listener qui
permet de déclencher
des traitements à la
réceptionn d’un
message asynchrone
Service JMS
Les Clients
Conteneur EJB
Le rôle du conteneur EJB est de:

Gérer le cycle de vie des composants EJB


 Instanciation
 Accès au bean
 Sérialisation
 Desérialisation
 Destruction du bean

Permettre aux EJB d’accéder aux services


d’infrastructures offerts par le serveur d’application JEE.
Services d’infrastructure d’un serveur d’application JEE:
Les beans session
Les beans sessions :
 Les beans sessions sont des composants conçus pour implémenter la logique de l'application.

 Une application comporte généralement plusieurs beans sessions qui sont individuellement chargés
d'une partie du traitement.
Les beans sessions sont alors des briques pour concevoir le traitement final global.
Exemple: Une application pour un commerce en ligne aura:
un bean session contenant la logique nécessaire pour gérer les utilisateurs.
un autre sera responsable de la liste des produits et des paniers des utilisateurs.

 Les beans sessions sont de deux types:


 les bean session à un état (stateful) pendant toute la durée de la session (c'est-à-dire conserver
l'état des attributs internes aux objets de façon à maintenir la conversation avec le client)
Ex Un panier d’achat
 Les bean session sans état (stateless), ce qui signifie qu'il fournit un accès à des méthodes distant
(utilisant Remote Method Invocation), mais ne conserve aucun résultat auquel le client pourrait
faire référence ultérieurement.
Ex Un catalogue
Bean Session sans état
 Stateless
 Ne contient aucun état (aucun attribut lié au client)
 Toutes les instances de ces beans sont donc équivalentes (sauf pendant l’exécution d’une méthode),
quelque soit leurs clients
 Peut donc être partagé par plusieurs clients
 Exemple : un catalogue, un « mailer »

Bean Session avec état


 Stateful
 Contient un état ayant une influence sur la façon dont les tâches sont traités entre deux appels de son
client
 Est affecté à un client
 Contient des attributs
 Une valeur dépendante du client
 Un stateful ne peut pas être partagé
 Permet d’enchaîner des traitements
Les beans entités
Les beans entités :
 Ce sont des objets qui utilisent le mécanisme de persistance (API JPA).
 Pour utiliser une base de données et stocker les valeurs des attributs de chacun
de ces beans entités.
 Avec un bean entité, le développeur ne voit pas du tout la base de données et
donc ne s'en occupe pas ; il peut alors passer tout son temps sur l'application
elle-même.
 Les beans entités lisent et écrivent les données dans des tables fournissant ainsi
une abstraction orienté objet d'une base de données relationnelle.
 Dans un scénario EJB type, lorsqu'un bean session doit accéder à des données,
il appelle les méthodes d'un bean entité.
 Par exemple, une application pour la gestion d'une école peut posséder un bean
entité nommé Etudiant qui possèdera une instance pour chaque étudiant inscrit.
Exemple : EJB session
Un Session Bean
L’étape1: définir l’interface à implémenter par l’EJB.
package tpejb.services;
import javax.ejb.Remote;
Étape 2: @remote package tpejb.services;
import javax.ejb.local;
public interface ToUpper {
@local
String toUpper(String data); Public interface ToUpperLocal{
ppp
} String toUpper(String data);
}

Ajouter ensuite l’annotation @remote si l'EJB sera accessible à distance


(via le protocole RMI) ou l'annotation @local si l’EJB sera dans la même
JMV que le client.
Si l’EJB est à la fois distant et local. Il faut dans ce cas deux interfaces.
Un bean avec un interface locale ne peut être utilisé que par un client
tournant dans la même JVM : une jsp, une servlet ou un autre ejb
L’étape 3: réaliser une implantation (le Bean Stateless )

package tpejb.implementation;
étape 2 import tpejb.services.ToUpper;
import javax.ejb.Stateless;
@Stateless(name= "EJB", description ="un premier test")
public class ToUpperImpl implements ToUpper, ToUpperLocal {
public String toUpper(String data) {
return data.toUpperCase();
}
}
Pour le bean Stateful, il suffit d’utiliser l’annotaion @Stateful.
 L'annotation @Stateless permet de typer votre EJB et de lui donner un nom (qui sera
utilisé par le client dans un lookup jndi pour accéder aux méthodes métiers) .
A ce stade vous pouvez déployer le JAR de votre projet dans le serveur d'applications.
Vérifiez qu'il n'y a pas d'erreur. Consultez la console de glassfish (et vérifiez que votre
application est bien présente, bien déployer et repérer le nom JNDI.
Mise en place du client en Local

1. Créer une application entreprise -un projet java EE-


2. Dans le sous projet de type EJB, créer un ejb session accessible en local.
3. Dans les sources du deuxième projet de type web application, on va
indiquer que l'on va « parler » au bean HelloWorld. Pour cela, Injecter
une instance du Bean avec le menu "call enterprise bean" :
public class ServletTest extends HttpServlet {  
    @EJB  
    private HelloWorldLocal helloWorld;  

4. Le @EJB est l'annotation de code qui va procéder à "l'injection de code"


lors de la compilation ou du déploiement. La variable helloWorld sera
initialisée par le code injecté et ne vaudra pas "null" comme cela pourrait
sembler.
5. Insérer un menu dans la page d’accueil pour tester.
Mise en place du client en Remote
 Nous allons créer un client pour un accès distant à l’EJB, celui-ci doit implémenter
l’interface Remote.
 Mettre en place une dépendance librairie entre le projet client et le projet EJB
public class ClientEjb2019 {
public static void main(String[] args) {
try {
Context initial = new InitialContext();
Object o = initial.lookup("ensat.tp.HelloWorldRemote");
System.out.println(((HelloWorldRemote) o).getMessage());
} catch (NamingException ex) {
Logger.getLogger(ClientEjb2019.class.getName()).log(Level.SEVERE, null, ex);
}}}
 « ensat.tp.HelloWorldRemote » le namming annuaire (JNDI) utilisé par le serveur
d’application et qui permet de chercher dans l’annuaire des objets instanciés
distants.
 Les paramètres de connexion JNDI sont précisés dans un fichier de configuration.
On crée un fichier de ressources « jndi.properties » à la racine du dossier source.
Propriété JNDI
• Pour glassfish:
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryIm
pl
• Il faut aussi joindre des jars pour le naming aux projets
Gestion du cycle de vie de l’EJB
Avec des annotations, les méthodes qui les suivront seront appelées par le S.A
lors des différentes étapes du cycle de vie de l’EJB.

@PostConstruct()
Appelé après l’instanciation
@PreDestroy
Après la destruction du composant
@init
Désigne la méthode d’initialisation d’un stateful
@remove
Désigne la méthode remove d’un composant

Utilisation
 2 méthodes
Ajout des méthodes dans le code métier du bean
Création d’une classe indépendante contenant les intercepteurs
Séparation du code métier et du code de gestion des cycles de vie
@Stateless
public class HelloWorldBean implements HelloWorld, HelloWorldHome {
public String sayHello(){ … }
@PostConstruct
public void onCreate() {
//Code de l’intercepteur …
}
}
public class MyInterceptor {
@PostConstruct
@Interceptors({MyInterceptor.class})
public void myCreate() { @Stateless
//Code de l’intercepteur … public class HelloWorldBean
} implements HelloWorld,
@PreDestroy HelloWorldHome
public void mydestroy() { {
//Code de l’intercepteur … public String sayHello()
} {
… return "Bonjour le monde";
} }
}
Développement d'un EJB Entity
Base de donnée
Structure de la table « Compte »

Attribut Type

id Long

solde double

Date_de_création date
L’entité Produit

package tpejb.dao;
Par défault, la table lié porte le nom de la
import java.io.Serializable; classe
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Produit implements Serializable{
@Id
Clés Primaire
private String id;
private String libelle;
private int quantiteEnStock;
public Produit() { Constructeur par défaut
super(); obligatoire
}
public Produit(String id, String libelle, int quantiteEnStock) {
this.id = id;
this.libelle = libelle;
this.quantiteEnStock = quantiteEnStock;
}
public String getLibelle() {
return libelle;
}
public void setLibelle(String libelle) {
this.libelle = libelle;
}
public int getQuantiteEnStock() {
return quantiteEnStock;
}
public void setQuantiteEnStock(int quantiteEnStock) {
this.quantiteEnStock = quantiteEnStock;
}
public String getId() {
return id;
}
public String toString() {
return "Produit n°" + id + " - " + libelle + " - quantité disponible : " +
quantiteEnStock;
}
}
Entity Bean Comptes

+ Constructeur sans arguments


+ Constructeur avec arguments
+ Getter et Setter
Quelques annotations importantes

Annotation Description
@Entity La classe est un bean entité
@Id L’objet ou la fonction qui suit est la clé
primaire de l’entité
@generatedValue[strategy=“…”] Définit une politique de génération
automatique de la clé-primaire
@Table[name=“…”] Assigne l’entité à une table spécifique
@Column[name= “…”] Assigne l’attribut qui suit à une colonne
spécifique de la table
Tester l’EJB Entity (1/3)

nous allons créer un EJB Session, comme application cliente de l’EJB Entity.
Pour manipuler l’EJB Entity:
Accès via l’injection d’ un EntityManager


@Remote
public interface GestionDeStock {
   public void ajouter(Produit produit);
   public Produit rechercherProduit(String id);
   public List<Produit> listerTousLesProduits();
}

….
@Stateless
public class GestionDeStockBean implements GestionDeStock {
    @PersistenceContext (UnitName=…)
   EntityManager em;

   public void ajouter(Produit produit) {


      em.persist(produit);
   }
    public Produit rechercherProduit(String id) {
      return em.find(Produit.class, id);
   }

}
Tester l’EJB Entity (2/3)
La spécification JPA standardise l'utilisation d'un fichier, nommé persistence.xml, qui permet
de préciser des paramètres techniques liés au mapping objet-relationnel, par exemple le nom
de la 'DataSource' à utiliser pour se connecter à la base de données.
Pour Utiliser la bases de données HSQLDB intégrée au serveur JBoss.
Dans le projet EJB, créer le sous-répertoire META-INF et y placer le fichier persistence.xml
suivant :

<persistence>
   <persistence-unit name="IntroEJB3">
      <jta-data-source>java:/DefaultDS</jta-data-source>
      <properties>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
      </properties>
   </persistence-unit>
</persistence>

Le nom 'IntroEJB3' est purement arbitraire, le nom de la DataSource est celui défini par JBoss,
la valeur 'update' de la propriété 'hibernate.hbm2ddl.auto' indique que nous souhaitons
qu'Hibernate crée la structure de données automatiquement et la mette à jour si nécessaire.
Tester l’EJB Entity (3/3)
 JBoss intègre un outil permettant de manipuler la base de données
HSQLDB.

 Pour ouvrir cet outil : accéder à la console d'administration de


JBoss via l'url http://localhost:8080/jmx-console, dans la section
nommée 'jboss', cliquer sur
'database=localDB,service=Hypersonic'. Dans la page qui
s'affiche, cliquer sur le bouton 'Invoke' qui se trouve sous la
signature de méthode 'void startDatabaseManager()'. L'outil
'HSQL Database Manager' est alors lancé (NB: cet outil est une
application cliente, il ne s'affiche pas dans le navigateur). Vérifier
la présence de la table 'PRODUIT‘.

 Créer ensuite l’application cliente dans Eclipse. Vérifier ensuite


que l’insertion, suppression, recherche des données s’effectuent
correctement.
Exemple à réaliser
Exemple1:
Créer l’entité Produit
Ecrire l’EJB session qui permet de gérer un stock
Ecrire une application cliente pour tester.

Exemple2 :
Une application qui donne une interface permettant de
lister des livres écrits par plusieurs auteurs.
Les entités Livre et Auteur
Relation entre entités:
one-to-many, many-to-one(bidirectionnelle)

Vous aimerez peut-être aussi