IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java EE Discussion :

Injection des EJB : quand et pourquoi ? [EJB]


Sujet :

Java EE

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 37
    Points : 39
    Points
    39
    Par défaut Injection des EJB : quand et pourquoi ?
    bonjour,

    je traine une incompréhension concernant les attributs des beans managés. Certains de leurs attributs doivent être injectés avec l'annotation @EJB, et d'autres non !
    Au départ, je pensais que @EJB s'imposait lorsque l'attribut était un objet d'une classe "maison" ...mais visiblement ce n'est pas tout à fait ça.
    A cette heure, je nourrie l'idée que cela concerne les attributs-object dont la classe hérite d'une classe "maison" ...
    Alors, avant de nourrir toutes les idées de la terre, je fais appel à vos lumières : quelle est la règle ?

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    @EJB sert à injecter un EJB. Ni plus ni moins.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 37
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    @EJB sert à injecter un EJB. Ni plus ni moins.
    alors ma question est mal formulée. Je fais une autre tentative :
    Qu'est-ce qui détermine si tel ou tel attribut doit être un EJB ?

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Un EJB permet entre autre, d'ajouter la gestion des transactions, la sécurité, la possibilité de garder un état entre deux requêtes dans le cas d'un statefull, faire de l'asynchrone à partir d'une file de message JMS dans le cas de message bean, etc...

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par IDtalc Voir le message
    Qu'est-ce qui détermine si tel ou tel attribut doit être un EJB ?
    Ce n'est pas l'attribut qui détermine si cela doit être un EJB, c'est l'EJB en lui même. L'attribut ne fait que suivre le fait que ce soit un EJB et que donc il faut l'injecter comme tel.

    Ce dont bénéficie un EJB en gros dont ne bénéficient pas les beans CDI:
    Toutes les annotations de securité et de transaction
    Peut être exporté pour être accessible à distance
    Possibilité de brancher des intercepteurs
    Reception des messages JMS (message driven beans)
    Propagation de sécurité inter domaine
    Méthodes asynchrones
    Pooling

    Si tu n'a pas besoin de ça, tu peux te contenter d'un bean CDI.

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 37
    Points : 39
    Points
    39
    Par défaut
    bien le bonjour,

    merci à vous deux. Je reste cependant encore dans le flou. Il est fort possible que l'information que je cherche figure déjà parmi vos réponses, mais que je ne sache pas la lire.
    Déballage de ce que je crois avoir compris : l'annotation @ManagedBean me permet de préserver l'objet coté serveur entre deux requêtes d'un même client.
    En gros, ça indique à la JVM du serveur : "ne delete pas trop vite cette d'instance, on risque d'en avoir besoin par la suite". Du coup, il lui faut aussi garder en mémoire les attributs ...et c'est là qu'intervient l'annotation @EJB ...mais uniquement dans des cas bien précis ! C'est sur ce point que la précision me manque.

    Prenons un exemple simple (qui fonctionne) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @SessionScoped
    @ManagedBean
    public class BeanVoiture {
     
    	private Voiture uneVoiture;
    	@EJB  
    	private DaoVoiture daoVoiture;
     
    	public BeanVoiture (){
    		uneVoiture= new Voiture();	
    	}
    	...
    Puisqu'on n'a pas besoin d'injecter uneVoiture, pourquoi doit-on injecter daoVoiture ?
    Serait-ce parce que toutes les instances de BeanVoiture (une par client) doivent se partager une seule et unique instance de daoVoiture ?
    ...ou encore que les instances de BeanVoiture ne doivent pas utiliser leur daoVoiture au même moment ?
    ça ressemble fortement à une espèce de stratégie pour gérer les conflits de CRUD, car la seule distinction intéressante entre ces deux objets, selon moi, c'est l'accès à la table "voitures" de daoVoiture.
    J'ai grand besoin d'être fixé pour de bon ; vous comprenez que je ne peux pas rester dans cette ignorance plus longtemps.
    (ne pas avoir le niveau en anglais, pour la prog, c'est un sacré handicap)

  7. #7
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    J'imagine que ton objet Voiture est un simple JavaBean.
    Tu gères toi même sa création dans le constructeur de ton BeanVoiture.
    Dans le cas d'une ressource injectée comme DaoVoiture, c'est ton serveur d'application qui gère cet aspect.
    En interne ton serveur possède un pool d'EJB DaoVoiture (que tu peux configurer), donc des instances déjà créées et prêtes à être injecter.
    Un EJB est un objet complexe donc plus lourd à construire.

    Le fait que ton ManagedBean survive entre deux requêtes est du à l'annotation SessionScope plutôt qu'à l'annotation ManagedBean.
    Change ton bean en RequestScope et tu auras perdu le contexte entre deux requêtes.

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par IDtalc Voir le message
    l'annotation @ManagedBean me permet de préserver l'objet coté serveur entre deux requêtes d'un même client.
    Non, l'annotation @ManagedBean signifie à CDI qu'il doit gérer le cycle de vie de ta classe.

    Du coup, il lui faut aussi garder en mémoire les attributs ...et c'est là qu'intervient l'annotation @EJB
    Non, l'annotation @EJB dit à CDI "quand tu crée BeanVoiture, il a besoin d'avoir accès à l'EJB DaoVoiture

    Puisqu'on n'a pas besoin d'injecter uneVoiture, pourquoi doit-on injecter daoVoiture ?
    On a pas "besoin" de l'injecter. C'est juste que c'est plus facile de l'injecter que d'aller rechecher à la main l'EJB dans le JNDI. Ca permet aussi de s'assurer que l'EJB est rendu au pool lorsque le ManagedBean en a fini avec lui.

    daovoiture est un EJB, il a besoin de toutes l'infrastructure EJB pour fonctionner (sinon on n'en ferait pas un EJB). Tu ne peux donc pas faire simplement un new dessus puisque cette instance serait hors infrastructure. Duc oup il faut demander poliment au constructeur une instance de l'EJB. Tu peux le faire via le JNDI en utilisant le nom complet de l'EJB, ou via l'annotation @EJB sur l'attribut, à condition que tu dois dans une classe elle même gérée par le conteneur.

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 37
    Points : 39
    Points
    39
    Par défaut
    un grand merci pour ces précisions, ça rectifie le tir ...mais je ne reconnais plus la cible lol
    Avant de m'effeuiller complètement sur ce topic, je vais me donner une chance de regagner un semblant de dignité et terminer mon instruction comme un grand.
    C'est bien pratique de questionner sur un forum et de passer plus tard pour récolter l'info, mais on oublie vite que cela doit rester une solution de dernier recours.
    Bon début de printemps à tous

  10. #10
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Pour info, un EJB est une classe spéciale qui tourne dans un conteneur spécial, le conteneur d'EJB.
    Ce qui fait qu'un EJB est un EJB, c'est que cette classe a l'annotation @Stateless ou @Stateful (ou @MessageDriven mais c'est un peu spécial)
    On peut également passer par un fichier ejb-jar.xml plutôt que les annotations...

    L'EJB implémente des méthodes d'une ou deux interfaces (en fonction des besoins).
    La première aura une annotation @Locale, la deuxième @Remote
    Quand on travaille au sein d'une même JVM, il est plutôt conseillé d'utiliser l'interface @Locale. On utilisera l'interface @Remote à partir d'une autre JVM.
    Techniquement, dans le cas d'une interface @Locale, on passe les paramètres directement (par référence aussi) alors qu'avec l'interface @Remote, on passe par la sérialisation/désérialisation des paramères (plus lourd mais incontournable à distance).

    Dans une classe utilisatrice (comme un @ManagedBean), on référence l'interface cible avec l'annotation @EJB, on fonction de celle qu'on choisit, on ne fait pas tout à fait la même chose mais en gros, ça revient au même.
    Il y a un piège courant avec les 2 modes qui est lié aux références de l'objet paramètre.
    Dans cet exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    private UnObjet monObjet;
    @EJB
    private MonInterfaceLocale monEJB;
     
    ...
    public void uneFonction()
    {
       monEJB.maMethode(monObjet);
    }
    à la fin de l'exécution de "maMethode", si la méthode modifie les propriétés de l'objet "monObjet", ton managedBean contiendra les modifications puisque tu as passé l'objet monObjet par référence.
    Si tu utilisais l'interface @Remote, ce ne serait pas le cas.
    Pour faire l'équivalent, il faudra que ta méthode renvoie l'objet, on aurait donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    monObjet = monEJB.maMethode(monObjet);
    (avec l'adaptation de l'interface et de l'implémentation de l'EJB qui va avec bien sûr )

    Une autre chose qui peut être surprenante dans le monde des EJBs et la notion de transaction et de conteneur EJB (donc avec la notion JPA).
    Avec un @Stateless (en gros), dès que tu sors du conteneur, la transaction est validée (commit).
    Ce qui peu être surprenant, c'est d'avoir une méthode qui ne lance pas d'exception dans la méthode mais "en dehors".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ...
    public void validate(MonEntity unEntity)
    {
       try
       {
          entityManager.persist(unEntity);
       }
       catch (Exception e)
       {
          System.out.println("p'tain, j'ai tout pété");
       }
    }
    On va supposer pour l'exemple que les propriétés de l'entity sont toutes obligatoires (not null) et qu'au moins un attribut est null.
    Tu ne passeras pas dans ton catch parce que c'est au commit que l'exception sera lancée, pas avant (donc en dehors de ta méthode)

    Autre chose dans ce contexte qu'il faut bien appréhender, c'est le cloisonnement du conteneur.
    Quand tu sors du conteneur d'EJB, les entity sont "détachées".
    Si dans une classe utilisatrice (du conteneur de servlets par exemple) tu faisais référence à une propriété non initialisée (typique du lazy loading), tu te prendrais une exception.

    Voilà, peut-être que ces quelques explications te permettront de mieux comprendre le fabuleux monde des EJBs
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Bonjour, les EJB sont des concepts complexes, ne te fie pas à ton interprétation, lit la documentation. Je parle des EJB au pluriel car il existe 3 familles d'EJB :
    * EJB Session Bean
    * EJB Message-Driven Bean (si tu fais du JMS)
    * EJB Persistance (si tu fais du JPA)

    En ce moment tu touches au premier concept cité, tu injectes tes beans via l'annotation @EJB. Un EJB est un Session Bean si ta classe est annoté avec @Stateful, @Stateless ou @Singleton.

    On parle de CDI plus haut, ce dernier est un concept proche d'EJB Session Bean car il permet de réaliser l'injection de dépendance par exemple mais CDI n'est pas EJB Session Bean. Aussi ne mélange pas les annotations entre ces deux concepts si tu ne veux pas avoir à faire à des conflits bizarres dans ton projet.

    Enfin tu utilises @ManagedBean, cela signifie très certainement que tu utilises le framework JSF. Cette annotation signifie simplement que le framework va gérer ta classe avec le scope indiqué. Si tu utilises JSF 2.2 ou plus je te conseille d'utiliser les annotations CDI comme sur le site d'Oracle.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 37
    Points : 39
    Points
    39
    Par défaut
    bon, je crois avoir à peu près compris ...du moins, suffisamment pour répondre à mes besoins immédiats. Ceci dit, ça ne tiendra pas longtemps, je le craint.
    Ces histoires de famille et d'interface ont quelque peu calmé mes ardeurs ; je regarderai de nouveau sous les jupes des EJB quand je serai plus grand.
    Allez en paix

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [EJB] [Débutant] Portabilité des EJB
    Par ruff15 dans le forum Java EE
    Réponses: 7
    Dernier message: 23/01/2008, 17h47
  2. Réponses: 8
    Dernier message: 11/01/2008, 05h51
  3. [Integration] Equivalent de l'interface Remote des EJB
    Par onlytoine dans le forum Spring
    Réponses: 36
    Dernier message: 07/01/2005, 14h55
  4. Compiler, Déployer des EJB avec ANT ?
    Par Johnbob dans le forum ANT
    Réponses: 3
    Dernier message: 28/09/2004, 16h04
  5. [JONAS][EJB]erreur sur la construction des EJB
    Par silvermoon dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 04/06/2004, 18h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo