Laboratoire SUPINFO des technologies SUN Introduction aux EJB - Enterprise JavaBeans - EJB – Enterprise JavaBeans Pré requis • J2SE • JMS EJB – Enterprise JavaBeans Objectifs • Connaître et comprendre le concept des EJB • Savoir créer et utiliser un SessionBean • Savoir créer et utiliser un EntityBean • Utilisation de l’utilitaire « deploytool » • Utilisation professionnelle avec JBoss et JBoss-IDE EJB – Enterprise JavaBeans Plan du cours • • • • • Présentation EJB Fonctionnel général et architecture SessionBean EntityBean MessageBean EJB – Enterprise JavaBeans Qu’est-ce qu’un EJB? • • • • • Entreprise JavaBean Composant serveur Écrit en Java Encapsule la logique métier Exécuté dans un conteneur EJB – Enterprise JavaBeans Avantages • Gestion transparente de la sécurité et des transactions • Application cliente -> Présentation • Séparation des couches • Portabilité / Pérennité • Développement simplifié • Client plus léger EJB – Enterprise JavaBeans Architecture - matériel Présentation Customer (web) Application Métiers Moteur de servlet Server app EJB Guichet / Admin (swing) ` Physique DataBase Oracle DataBase MSSQL DataBase AS400 LDAP Directory EJB – Enterprise JavaBeans Quand les utiliser ? • Application évolutive • Transactions / accès concurrents aux données • Nombreux clients différents (Swing, web …) EJB – Enterprise JavaBeans 3 types d’EJB • Session : Client unique / WebService • Entity : Entité métier / persistant • Message-Driven : Listener JMS EJB – Enterprise JavaBeans Accès clients via les interfaces • • • • Nécessaire aux Session et Entity Beans Définissent la vue du client Couche d’abstraction supplémentaire Différents types d’accès: – Remote – Local – Web Services EJB – Enterprise JavaBeans Clients distants • JVM différentes (réseau) de l’EJB • Composant Web, Application cliente J2EE ou autre EJB • Localisation de l’EJB transparente • Remote Interface • Home Interface EJB – Enterprise JavaBeans Clients locaux • • • • • Même JVM que l’EJB Composant Web ou autre EJB Localisation de l’EJB non transparente Local Interface Local Home Interface EJB – Enterprise JavaBeans Interfaces distantes ou locales • Locales : – CMR (Component Managed Relation) – Relations étroites – + performant • Distantes : – Client J2EE – Serveur web <> serveur applicatif – + de flexibilité EJB – Enterprise JavaBeans Web Services • • • • HTTP / SOAP / WSDL Stateless Session Bean Web Service Endpoint Interface Pas de Home Interface EJB – Enterprise JavaBeans Récapitulatif - interfaces JVM distante JVM locale (serveur App) Local interface JNDI Client distant EJB Remote interface RMI LocalHome interface Remote interface Home interface Web service Home interface Endpoint interface ` Client local EJB – Enterprise JavaBeans Paramètres des méthodes • Isolation – Copie des paramètres ou non ? – Encapsulation dans des JavaBean • Granularité – Paramètres complets – Multiple getters EJB – Enterprise JavaBeans Architecture – logiciel Distants Session Bean CustomerService Stateless Session Bean CounterService Statefull Session Bean AdminService Statefull Locaux DB Entity Beans CMP • Account • Operation Oracle Entity Beans CMP • Task MsSql Entity Beans CMP • Rate As400 Entity Beans BMP • CustomerLdap Ldap EJB – Enterprise JavaBeans Contenu de l’EJB • Descripteur de déploiement • Classe du bean • Interfaces (Session et Entity Bean) – Remote et Home – Local et Local Home – Web Service Endpoint • Classes Helper EJB – Enterprise JavaBeans Nomenclature Elément Syntaxe Exemple Nom de l’Enterprise bean <nom>Bean AccountBean EJB JAR <nom>JAR AccountJAR Classe de l’Enterprise bean <nom>Bean AccountBean Home interface <nom>Home AccountHome Remote interface <nom> Account Local home interface <nom>LocalHome AccountLocalHome Local interface <nom>Local AccountLocal Abstract schema <nom> Account EJB – Enterprise JavaBeans Déploiement • Créer l’EJB JAR • L’ajouter à un EAR • Déployer l’EAR EJB – Enterprise JavaBeans Session Bean • • • • Représente un client unique Equivaut à une session interactive Non persistant Stateless ou Stateful EJB – Enterprise JavaBeans Quand utiliser les session beans ? • Une seule instance par client • État non persistant, courte durée • Implémentation d’un web service EJB – Enterprise JavaBeans Stateless Session Bean • Ne maintiennent pas l’état de la conversation • Instances non liées à un client particulier • Supportent de multiple clients • Évolutif à la charge • Performants EJB – Enterprise JavaBeans Quand utiliser les stateless ? • • • • Données non spécifiques à un client Méthodes génériques Utilisation fréquente Récupérer des données en lecture seule EJB – Enterprise JavaBeans Stateless Session – Bean (1) import javax.ejb.*; import java.math.*; public class ConverterBean implements SessionBean { BigDecimal francRate = new BigDecimal("0,15245"); BigDecimal euroRate = new BigDecimal("6.55957"); public BigDecimal euroToFranc(BigDecimal euros) { BigDecimal result = euros.multiply(francRate); return result.setScale(2, BigDecimal.ROUND_UP); } public BigDecimal francToEuro(BigDecimal franc) { BigDecimal result = franc.multiply(euroRate); return result.setScale(2, BigDecimal.ROUND_UP); } EJB – Enterprise JavaBeans Stateless Session – Bean (2) public ConverterBean() {} public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) {} } EJB – Enterprise JavaBeans Stateless Session – Home Interface import java.rmi.RemoteException; import javax.ejb.*; public interface ConverterHome extends EJBHome { Converter create() throws RemoteException, CreateException; } EJB – Enterprise JavaBeans Stateless Session – Remote Interface import javax.ejb.EJBObject; import java.rmi.RemoteException; import java.math.*; public interface Converter extends EJBObject { public BigDecimal euroToFranc(BigDecimal euros) throws RemoteException; public BigDecimal francToEuro(BigDecimal franc) throws RemoteException; } EJB – Enterprise JavaBeans Stateless Session – Client(1) import javax.naming.*; import javax.rmi.PortableRemoteObject; import java.math.BigDecimal; public class ConverterClient { public static void main(String[] args) { try { Context initial = new InitialContext(); Context myEnv = (Context) initial.lookup("java:comp/env"); Object objref = myEnv.lookup("ejb/SimpleConverter"); ConverterHome home = (ConverterHome) PortableRemoteObject.narrow(objref, ConverterHome.class); EJB – Enterprise JavaBeans Stateless Session – Client (2) Converter currencyConverter = home.create(); BigDecimal param = new BigDecimal("100.00"); BigDecimal amount = currencyConverter.euroToFranc(param); System.out.println(amount); } catch (Exception e) { e.printStackTrace(); } } } EJB – Enterprise JavaBeans Cycle de vie – Stateless Session Bean • setSessionContext() • create() • ejbCreate() • remove() • ejbRemove() EJB – Enterprise JavaBeans Récapitulatif – interfaces => bean Interfaces Home (local & remote) public Order create() public Order create(String orderId) Local & Remote public ArrayList getItems() public String getCustomerId() public double getTotalPrice() Bean public Order ejbCreate() public Order ejbCreate(String orderId) public ArrayList getItems() public String getCustomerId() public double getTotalPrice() EJB – Enterprise JavaBeans Stateful Session Bean • • • • Session unique client-bean Conserve l’état conversationnel Durée de vie égale à la session Peut être sauvegardé (cas particulier) EJB – Enterprise JavaBeans Quand utiliser les stateful ? • Interaction entre le bean et le client • Conserver les informations durant l’exécution de méthode • Liaison avec d’autres composants (vue simplifiée) EJB – Enterprise JavaBeans Stateful Session – Bean (1) import java.util.*; import javax.ejb.*; public class CartBean implements SessionBean { String customerName, customerId; Vector contents; public void ejbCreate(String person) throws CreateException { … } public void ejbCreate(String person,String id) throws CreateException { ... } public void addBook(String title) { contents.addElement(title); } public void removeBook(String title) throws BookException { … } public Vector getContents() { return contents; } … } EJB – Enterprise JavaBeans Stateful Session – Home Interface import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface CartHome extends EJBHome { Cart create(String person) throws RemoteException, CreateException; Cart create(String person, String id) throws RemoteException, CreateException; } EJB – Enterprise JavaBeans Stateful Session – Remote Interface import java.util.*; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Cart extends EJBObject { public void addBook(String title) throws RemoteException; public void removeBook(String title) throws BookException, RemoteException; public Vector getContents() throws RemoteException; } EJB – Enterprise JavaBeans Stateful Session – Client(1) import java.util.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; public class CartClient { public static void main(String[] args) { try { Context initial = new InitialContext(); Object objref = initial.lookup("java:comp/env/ejb/SimpleCart"); CartHome home = (CartHome) PortableRemoteObject.narrow(objref, CartHome.class); Cart shoppingCart = home.create("Duke DeEarl", "123"); EJB – Enterprise JavaBeans Stateful Session – Client (2) shoppingCart.addBook("The Martian Chronicles"); shoppingCart.addBook("2001 A Space Odyssey"); shoppingCart.addBook("The Left Hand of Darkness"); Vector bookList = new Vector(); bookList = shoppingCart.getContents(); Enumeration enumer = bookList.elements(); while (enumer.hasMoreElements()) { String title = (String) enumer.nextElement(); System.out.println(title); } shoppingCart.removeBook("Alice in Wonderland"); shoppingCart.remove(); System.exit(0); … } EJB – Enterprise JavaBeans Stateful - BookException public class BookException extends Exception { public BookException() {} public BookException(String msg) { super(msg); } } EJB – Enterprise JavaBeans Stateful - idVerifier public class IdVerifier { public IdVerifier() {} public boolean validate(String id) { boolean result = true; for (int i = 0; i < id.length(); i++) { if (Character.isDigit(id.charAt(i)) == false) { result = false; } } return result; } } EJB – Enterprise JavaBeans Cycle de vie – Stateful Session Bean • • • • • • • create() setSessionContext() ejbCreate() ejbPassivate() ejbActivate() remove() ejbRemove() EJB – Enterprise JavaBeans Entity Bean • • • • • • Objet métier (client, facture, produit, …) Persistant (BMP || CMP) Accès partagés Correspondance avec table BDD Possèdent des clés primaires Relations inter-beans EJB – Enterprise JavaBeans Cycle de vie – Entity Bean • • • • • setEntityContext() create() ejbCreate() ejbPostCreate() ejbActivate() EJB – Enterprise JavaBeans Bean Managed Persistance • Géré par développeur : – Schéma table – Accès database – Relation – Transaction … • Flexible EJB – Enterprise JavaBeans BMP - Normes • • • • • Classe public Ne peut être abstract ou final Constructeur vide Aucune méthode finalize() Implements EntityBean EJB – Enterprise JavaBeans BMP – ejbCreate • Insertion dans la base de données (INSERT) • Initialise les variables d’instances • Retourne la clé primaire public String ejbCreate(String champ0, String champ1, BigDecimal champ2 …) throws CreateException EJB – Enterprise JavaBeans BMP - ejbPostCreate • Appelée automatiquement après ejbCreate • Liaison entre ejbCreate et ejbPostCreate • Actions après la création (liaison avec d’autres ejbs …) public String ejbPostCreate(String champ0, String champ1, BigDecimal champ2 …) throws CreateException EJB – Enterprise JavaBeans BMP – ejbRemove • Suppression de la base de données (DELETE) public void ejbRemove() EJB – Enterprise JavaBeans BMP – ejbLoad / ejbStore • • • • Synchronisation par le conteneur ejbLoad : Database => Ejb (SELECT) ejbStore : Ejb => Database (UPDATE) Exception : NoSuchEntityException public void ejbLoad() public void ejbStore() EJB – Enterprise JavaBeans BMP – Finders • Récupération d’EntityBean (SELECT) • Obligatoire : ejbFindByPrimaryKey() – Clé primaire en paramètre – Clé primaire en retour • Optionel : ejbFind[ByOther](…) public String ejbFindByPrimaryKey(String primaryKey) throws FinderException public String / Collection ejbFind[ByOther](…) throws FinderException EJB – Enterprise JavaBeans Récapitulatif – interfaces => bean Interfaces Home (local & remote) public Order create() public Order create(String orderId) public Order findByPrimaryKey(String orderId) public Collection findByProductId(String productId) Local & Remote public ArrayList getLineItems() public String getCustomerId() public double getTotalPrice() public String getStatus() Bean public Order ejbCreate() public Order ejbCreate(String orderId) public Order ejbFindByPrimaryKey( String orderId) public Collection ejbFindByProductId( String productId) public ArrayList getLineItems() public String getCustomerId() public double getTotalPrice() public String getStatus() EJB – Enterprise JavaBeans BMP – Schéma table CREATE TABLE savingsaccount (id VARCHAR(3) CONSTRAINT pk_savingsaccount PRIMARY KEY, firstname VARCHAR(24), lastname VARCHAR(24), balance NUMERIC(10,2) ); EJB – Enterprise JavaBeans BMP – SavingsAccountBean public class SavingsAccountBean implements EntityBean { …. } EJB – Enterprise JavaBeans BMP – SavingsAccount import javax.ejb.EJBObject; import java.rmi.RemoteException; import java.math.BigDecimal; public interface SavingsAccount extends EJBObject { public void debit(BigDecimal amount) throws InsufficientBalanceException, RemoteException; public void credit(BigDecimal amount) throws RemoteException; public String getFirstName() throws RemoteException; public String getLastName() throws RemoteException; public BigDecimal getBalance() throws RemoteException; } EJB – Enterprise JavaBeans BMP – InsufficientBalanceException public class InsufficientBalanceException extends Exception { public InsufficientBalanceException() {} public InsufficientBalanceException(String msg) { super(msg); } } EJB – Enterprise JavaBeans BMP - SavingsAccountClient public class SavingsAccountClient { public static void main(String[] args) { try { Context initial = new InitialContext(); Object objref = initial.lookup("java:comp/env/ejb/SimpleSavingsAccount"); SavingsAccountHome home = (SavingsAccountHome) PortableRemoteObject.narrow(objref, SavingsAccountHome.class); BigDecimal zeroAmount = new BigDecimal("0.00"); SavingsAccount duke = home.create("123", "Duke", "Earl", zeroAmount); duke.credit(new BigDecimal("88.50")); duke.debit(new BigDecimal("20.25")); BigDecimal balance = duke.getBalance(); System.out.println("balance = " + balance); … } EJB – Enterprise JavaBeans Container Managed Persistence • • • • • • Aucun accès à la BDD dans le code Portable Abstract Schema – EJBQL Champs persistants Champs relationnels Descripteur de déploiement complet EJB – Enterprise JavaBeans CMR - Type de relations • • • • One to One (1 à 1) One to Many (1 à n) Many to One (n à 1) Many to Many (n à m) • Unidirectionnelle || Bidirectionnelle EJB – Enterprise JavaBeans CMR & BMP – Différences ? Aspect Container-Managed Bean-Managed Définition de la classe Abstract Not abstract Accès base de données Conteneur Développeur Etat persistant Champs persistants virtuels Variables d’instance Getters / Setters Requises Aucune findByPrimaryKey Conteneur Développeur finder personnalisés Conteneur (requêtes EJB QL) Développeur Méthodes select Conteneur Aucune Valeur de retour de ejbCreate null Clé primaire EJB – Enterprise JavaBeans CMP - Normes • • • • • • Classe abstract Implements EntityBean Constructeur vide Getter et setter : public abstract Aucune méthode finalize() Méthode(s) ejbCreate(…) retourne(nt) null EJB – Enterprise JavaBeans CMP – RosterApp Architecture • Vue d’ensemble de l’application EJB – Enterprise JavaBeans CMP – RosterApp Database EJB – Enterprise JavaBeans CMP – RosterApp Relationships EJB – Enterprise JavaBeans CMP – RosterApp Code • Cf. Cours • Détails de LeagueBean : – – – – – – – – public abstract String getLeagueId(); public abstract void setLeagueId(String id); public abstract String getName(); public abstract void setName(String name); public abstract String getSport(); public abstract void setSport(String sport); public String ejbCreate(String id, String name, String sport) public void ejbPostCreate(String id, String name, String sport) EJB – Enterprise JavaBeans Message-Driven Bean - présentation • Permet le traitement de messages asynchrones • Listener de message JMS • Sources de messages différents : clients, autres beans, application web, … EJB – Enterprise JavaBeans Différences avec les autres beans • • • • Pas d’interface Similaire au Stateless Session Bean Pool d’instance Une seule instance pour de multiples clients EJB – Enterprise JavaBeans Caractéristiques • • • • • Exécuter à la réception d’un message Appelé de manière asynchrone Durée de vie courte Non persistant (sans état) Peuvent être au courant des transactions EJB – Enterprise JavaBeans Avantages des Messages-Driven • Réception asynchrone • Non bloquant • Évite la surcharge du serveur EJB – Enterprise JavaBeans MessageBean - exemple • MessageBean - exemple EJB – Enterprise JavaBeans Conclusion EJB – Enterprise JavaBeans - Questions ? [email protected]