|
EJB 2 - Les Entreprise Java Bean (JavaBeans)
4.Les EJB : la théorie
Nous allons, dans cette partie, étudier les différents
composants que l’on doit fournir pour un EJB. Nous décrirons
de façon générique l’ensemble des règles
à respecter. Nous appliquerons ces règles dans le
prochain chapitre.
4.1.Les différentes étapes
de création d’un ejb
4.1.1.Interfaces
Le contenu de ce chapitre s'applique uniquement aux session beans et
entity beans.
Puisque les message-driven beans ont un modèle de
programmation différent, ils n'ont pas d’interfaces
définissant l'accès de client.
Un client peut accéder à un session bean ou un entity
bean seulement à travers les méthodes définies
dans les interfaces du bean. Ces interfaces définissent la vue
qu’a le client sur le bean. Tous les autres aspects du bean
(implémentations de méthodes, paramètres du
descripteur de déploiement, schémas abstraits et les
accès aux bases de données) ne sont pas visibles par le
client.
Les interfaces bien conçues simplifient le développement
et la maintenance des applications de J2EE. Faire des interfaces
propres protège, non seulement, les clients de la complexité
du tier EJB, mais permet aussi aux beans d’avoir des
modifications internes sans affecter les clients. Par exemple, même
si vous passez un entity bean d’une gestion de persistance par
le bean (BMP) vers une gestion par le conteneur (CMP), vous n’aurez
pas à modifier le code du client. En revanche, si vous désirez
changer les définitions de méthode dans les interfaces,
vous devrez modifier le code client de la même façon.
Par conséquent, pour isoler vos clients des changements
possibles des beans, il est important de concevoir soigneusement vos
interfaces.
Quand vous concevez une application J2EE, une des premières
décisions que vous devez prendre est le type d'accès
client autorisé par les EJB : remote, local, web
services.
Clients distants
Un client distant d'un enterprise bean a les traits suivants :
-
Il peut fonctionner sur une machine différente et une machine
virtuelle Java différente (JVM) de l’enterprise bean
qu'il accède (il n’est pas nécessaire de
l’exécuter sur une JVM différente).
-
Ce peut être composant web, une application cliente J2EE, ou
un autre bean d’entreprise.
-
Pour un client distant, l'endroit où est situé
l’enterprise bean est transparent.
Pour créer un enterprise bean avec accès distant, vous
devez coder une interface « remote interface »
et une interface « home interface ». La remote
interface définit les méthodes métiers qui
sont spécifiques au bean. Par exemple, la remote interface
d’un bean appelé BankAccountEJB pourrait avoir des
méthodes métiers appelées deposit()
et credit().
L’home interface définit les méthodes du
cycle de vie du bean : create() et remove().
Pour les entity beans, la home interface définit également
les méthodes finder et les méthodes home. Les méthodes
finder sont utilisées pour localiser les entity beans. Les
méthodes home sont des méthodes métiers qui sont
appelées sur toutes les instances d'une classe entity bean. Le
schéma ci-dessous montre comment les interfaces contrôlent
la vue cliente d'un bean d'entreprise.

Interfaces d’un Enterprise Bean avec accès distant
Clients locaux
Un client local a les caractéristiques suivantes :
-
Il doit être exécuté sur la même JVM que
l’enterprise bean auquel il accède.
-
Il peut être un composant web ou un autre enterprise bean.
-
Pour le client, l’endroit où se situe l’enterprise
bean auquel il accède n’est pas transparent.
-
Il s’agit souvent d’un entity bean qui a une relation
(gérée par le conteneur) avec un autre entity bean.
Pour construire un bean d’entreprise qui permet un accès
local, vous devez coder l’interface « local
interface » et l’interface « local home
interface ». La local interface définit les
méthodes métiers, la local home interface
définit son cycle de vie et les méthodes finder.
Interfaces locales et
relations gérées par le conteneur
Si un entity bean est la cible d'une relation géré par
le conteneur (CMR), alors il doit avoir des interfaces locales. La
direction de la relation détermine si un bean est la cible ou
non. Sur le schéma 1-1, par exemple, ProductBean est la cible
d'une relation unidirectionnelle avec LineItemBean. Puisque
LineItemBean accède à ProductBean localement,
ProductBean doit avoir des interfaces locales. LineItemBean doit
également avoir des interfaces locales, non pas en raison de
son rapport avec ProductBean mais parce que c'est la cible d'une
relation avec OrderBean. Et parce que le rapport entre LineItemBean
et OrderBean est bidirectionnel, les deux beans doivent avoir des
interfaces locales.
Puisqu'ils ont besoin d’un accès local, les entity beans
qui participent à une relation gérée par le
conteneur doivent résider dans le même fichier EJB JAR.
L'avantage premier de cet accès local est d’accroître
les performances, les appels locaux sont habituellement plus rapide
que des appels à distance.
Choisir entre accès
distant et accès local
La décision concernant le type d'accès dépend
des facteurs suivants :
Container-Managed Relationships (CMR) : Si un entity bean
est la cible d’une relation gérée par le
conteneur, il doit utiliser un accès local.
Relations étroites des beans : Les bean
étroitement liés sont interdépendants. Par
exemple, des OrderBean possèdent un ou plusieurs LineItemBean,
qui ne peuvent pas exister sans l’OrderBean auquel ils
appartiennent. Les entity beans OrderBean et LineItemBean qui
modélisent cette relation sont étroitement liés.
Les beans ayant des relations étroites sont de bons candidats
pour l'accès local. Puisqu'ils fonctionnent ensemble comme une
seule unité logique, ils appellent probablement souvent leurs
méthodes respectives et tireraient donc bénéfice
des performances accrues possible grâce à l'accès
local.
Type de client : Si un enterprise bean est consulté
par des applications clientes J2EE, alors il devrait permettre
l'accès à distance. Dans un environnement de
production, ces clients fonctionnent presque toujours sur machines
différentes du serveur J2EE. Si les clients des beans
d'entreprise sont des composants web ou d'autres beans d'entreprise,
alors le type d'accès dépend de la façon dont
vous voulez distribuer vos composants.
Distribution de composant : Les applications J2EE sont
extensibles parce que leurs composants de côté serveur
peuvent être distribués à travers de multiples
machines. Dans une application distribuée, par exemple, les
composants web peuvent fonctionner sur un serveur différent du
serveur des enterprise beans auxquels ils accèdent. Dans ce
scénario, les beans d'entreprise devraient permettre l'accès
à distance.
Performance : En raison des facteurs comme la latence du
réseau, les appels à distance peuvent être plus
lents que des appels locaux. D'autre part, si vous distribuez des
composants à travers différents serveurs, vous pourriez
améliorer les performances globales de l'application. La
performance réelle peut changer suivant l’environnement.
Néanmoins, vous devriez garder à l'esprit la manière
dont la conception de votre application pourrait affecter
l'exécution.
Si vous n’êtes pas sûr que du type d'accès
qu’un bean d'entreprise devrait avoir, choisissez alors l'accès
distant. Cette décision vous offre plus de flexibilité.
Par la suite, vous pourrez distribuer vos composants pour les adapter
aux demandes croissantes sur votre application.
Dans de rares cas, il est possible qu’un enterprise bean
permette un accès distant et local. Un tel bean exigerait les
deux types d’interfaces distantes et locales.
Clients de type web services
Un client de type web service peut accéder à une
application J2EE de deux manières. D'abord, le client peut
accéder à un web service créé avec
JAX-RPC (pour plus d'information, consultez le cours sur les web
services).
En second lieu, un web service peut appeler les méthodes
métiers d'un stateless session bean. Les autres types de beans
d'entreprise ne peuvent pas être accessibles par des clients de
type web service.
À la seule condition qu’il utilise les protocoles
corrects (HTTP, SOAP, WSDL), n'importe quel client de type web
service peut accéder à un stateless session bean, que
le client soit écrit ou non en Java. Le client ne sait,
éventuellement, même pas quelle technologie implémente
le service - stateless session bean, JAX-RPC, ou une autre
technologie. En outre, les enterprise beans et les composants web
peuvent être des clients de web services. Cette flexibilité
vous permet d'intégrer des applications J2EE avec les web
services.
Un web service accède à un stateless session bean à
travers l’interface « web service endpoint
interface » du bean. Comme une interface distante, une web
service endpoint interface définit les méthodes
métiers du bean. Contrairement à une interface
distante, une web service endpoint interface n'est pas
accompagnée d'une home interface, qui définit
les méthodes du cycle de vie du bean. Les seules méthodes
du bean qui peuvent être appelées par un web service
sont les méthodes métiers qui sont définies dans
la web service endpoint interface.
Paramètres des
méthodes et accès
Le type d'accès affecte les paramètres des méthodes
du bean qui sont appelées par les clients. Les points suivants
s'appliquent non seulement aux paramètres de méthode,
mais également aux valeurs de retour de méthode.
Isolation
Les paramètres des appels distants sont plus isolés que
ceux des appels locaux. Avec des appels distants, le client et le
bean travaillent sur des copies différentes de l’objet
passé en paramètre. Si le client change la valeur de
l'objet (le paramètre de la méthode), la valeur de la
copie dans le bean, elle, ne change pas. Cette couche d'isolement
peut aider à protéger le bean si le client modifie
accidentellement les données.
Dans un appel local, le client et le bean peuvent modifier le même
objet passé en paramètre. En général,
vous ne devriez pas compter sur cet effet secondaire des appels
locaux. Peut-être un jour vous voudrez distribuer vos
composants, remplaçant les appels locaux par des distants.
Semblable aux clients distants, les web services travaillent sur des
copies différentes des paramètres par rapport au bean
qui implémente le web service.
Granularité des données consultées
Puisque les appels à distance sont susceptibles d'être
plus lents que des appels locaux, les paramètres dans les
méthodes distantes devraient être relativement complet.
En effet, s’ils contiennent l’ensemble des informations,
peu d'appels sont nécessaires. Pour la même raison, les
paramètres des méthodes appelées par des web
services devraient également être complets.
Par exemple, supposons qu'un entity bean CustomerEJB soit consulté
à distance. Ce bean aurait une seule méthode getter
qui retourne un objet CustomerDetails, qui encapsule toutes les
informations relatives au client. Mais si CustomerEJB doit être
consulté localement, il pourrait avoir un getter pour
chaque variable d'instance : getFirstName(),
getLastName(),
getPhoneNumber(),
et ainsi de suite. Puisque les appels locaux sont rapides, les appels
multiples à ces getters ne dégraderaient pas de
manière significative les performances.
4.1.2.Classe bean (implémentation)
La classe bean d’un EJB est la classe d’exécution
de ce composant. En effet, c’est dans cette classe que vous
devez effectuer l’ensemble des actions liées à
votre EJB. L’ensemble des méthodes déclarées
dans les interfaces (distantes / locales) devront être
implémentées dans cette classe.
4.1.3.Descripteur de déploiement
Le descripteur de déploiement joue un rôle principal
dans les EJB. En effet, c’est lui qui coordonne l’ensemble
des éléments (interfaces, classe …).
La taille de ce fichier augement en fonction du nombre d’EJB à
déployer mais également du type de ces EJB. Nous verons
plus en détail les options de ce fichier dans les sections
suivantes.
Voici un exemple de descripteur :
<?xml
version="1.0"?>
<!DOCTYPE
ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans
1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>CabinEJB</ejb-name>
<home>com.titan.cabin.CabinHomeRemote</home>
<remote>com.titan.cabin.CabinRemote</remote>
<ejb-class>com.titan.cabin.CabinBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.Integer</prim-key-class>
<reentrant>False</reentrant>
<abstract-schema-name>Cabin</abstract-schema-name>
<cmp-field><field-name>id</field-name></cmp-field>
<cmp-field><field-name>name</field-name></cmp-field>
<cmp-field><field-name>deckLevel</field-name></cmp-field>
<cmp-field><field-name>shipId</field-name></cmp-field>
<cmp-field><field-name>bedCount</field-name></cmp-field>
<primkey-field>id</primkey-field>
<security-identity><use-callers-identity/><security-identity>
</entity>
</enterprise-beans>
<assembly-descriptor>
...
</assembly-descriptor>
</ejb-jar>
Voici une description de chacune des balises :
-
ejb-jar : est l’élément racine du document,
tous les autres éléments doivent se trouver à
l’intérieur de celui-ci
-
entreprise-bean : tous les EJB déclaré dans ce
fichier doivent se trouver à l’intérieur de
cette section
-
entity : déclare un Entity Bean
-
session : déclare un Session Bean
-
ejb-name : nom de l’EJB
-
home : indique la home interface à utiliser
-
remote : indique la remote interface à utiliser
-
ejb-class : indique la classe du bean à utiliser
-
persistence-type : définit le type de persistence pour
l’entity
-
prim-key-class : définit la classe de la clé
primaire
-
reentrant : autorise ou non le « reentrant
loopbacks »
-
abstract-schema-name : nom abstrait du bean dans le schema
-
cmp-field : déclare un champ persistant
-
field-name : indique le nom du champ persistant
-
primkey-field : indique le champ qu’il faut utiliser en
clé primaire
-
security-identity : déclare le niveau de sécurité
(les détails seront vu plus loin)
L’autre partie du descripteur de déploiement
est l’assembly-descriptor :
<ejb-jar>
<enterprise-beans>
...
<enterprise-beans>
<assembly-descriptor>
<security-role>
<description>
This
role represents everyone who is allowed full access
to
the Cabin EJB.
</description>
<role-name>everyone</role-name>
</security-role>
<method-permission>
<role-name>everyone</role-name>
<method>
<ejb-name>CabinEJB</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<container-transaction>
<method>
<ejb-name>CabinEJB</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
Cette section permet de définir les autorisations globales
pour l’ensemble des EJB déclarés. Cette section
est séparée de celle des EJB car on peut appliquer pour
plusieurs EJB une même stratégies de sécurité.
De plus, il est intéressant de séparer les deux
sections car il se peut que 2 groupes différents travaillent
sur ces deux sections différentes (optimisation pour le
travail).
-
assembly-descriptor : contient l’ensemble des
descriptions de sécurité
-
security-role : déclare un type de sécurité
-
method-permission : définit des permissions liées
à des méthodes
L’ensemble de la sécurité au sein des EJB sera
expliqué plus en détail aux chapitres suivants.
4.1.4.Assemblage
Pour développer un enterprise bean, vous devez fournir les
fichiers suivants :
-
Descripteur de déploiement : Un fichier XML qui
spécifie les informations relatives au bean tel que son type
de persistance et ses attributs de transaction. L’utilitaire
deploytool crée le descripteur de déploiement à
travers l’étape de création d’un nouveau
bean d’entreprise.
-
Classe de l’enterprise bean : implémente
les méthodes définies dans les interfaces qui suivent.
-
Interfaces : les interfaces « remote »
et « home » sont requises pour les
accès distants. Pour un accès local, les interfaces
« local » et « local
home » sont requises. Pour accéder au bean via
des web services, l’interface « web service
endpoint » est nécessaire. Notez que ces
interfaces ne sont pas utilisées par les message-driven
beans.
-
Classes Helper : d’autres classes
nécessaires à la classe de l’enterprise bean,
tels que des exceptions et des classes utilitaires.
Vous empaquetez les fichiers de la liste précédente
dans un fichier EJB JAR, le module qui enregistre l’enterprise
bean. Un fichier EJB JAR est portable et peut être utilisé
par différentes applications. Pour assembler une application
J2EE, vous empaquetez un ou plusieurs modules (des fichiers EJB JAR)
dans un fichier EAR, l’archive qui contient l’application.
Quand vous déployez le fichier EAR qui contient les fichiers
EJB JAR des beans, vous déployez aussi l’enterprise bean
sur le Serveur Applicatif. Vous pouvez aussi déployer un EJB
JAR qui n’est pas contenu dans un fichier EAR.

Structure d’un JAR Enterprise Bean
4.1.5.Le déploiement
Le déploiement d’EJB se fait uniquement par fichier JAR
(ou EAR contenant le/les JAR). La manière de déployer
un EJB sur un serveur d’application n’est pas
standardisé. Très souvent, il suffit de copier le JAR
ou EAR dans un dossier de déploiement spécifique
(Exemple : dossier deploy pour JBoss).
D’autres serveurs utilisent leur interface d’administration
pour effectuer cette opération (envoie du fichier à
déployer via HTTP).
4.1.6.Le client
Commençons par rappeler que les EJB sont des objets
distribués. Ils s’incrivent donc dans un système
de nommage et de relation client/serveur.
Le client doit effectuer différentes étapes :
-
Paramétrer l’environnement client.
-
Connexion au serveur de nommage du serveur d’application
(JNDI)
-
Récupérer, via l’url, le stub correspondant à
la classe Home de l’EJB (JNDI / RMI)
-
Effectuer les appels aux méthodes distantes.
Nous verrons en détail l’ensemble des APIs à
utiliser pour chacune de ces étapes dans le chapitre 3.
|
|
 |