111 votes

Comment CDI et EJB se comparent-ils ? interagissent-ils ?

J'ai du mal à comprendre comment les deux interagissent et où se situe la frontière entre les deux. Se chevauchent-ils ? Y a-t-il des redondances entre eux ?

Je sais qu'il y a des annotations associées aux deux, mais je n'ai pas réussi à trouver une liste complète pour les deux avec de brèves descriptions. Je ne sais pas si cela pourrait aider à clarifier leurs différences ou leurs chevauchements.

Vraiment juste confus. Je (pense) comprendre assez bien EJB, je suppose que j'ai du mal à comprendre exactement ce que CDI apporte et comment il supplante ou améliore ce que EJB offre déjà.

5 votes

Cette question arrive en tête de la recherche Google "EJB CDI difference", mais j'ai trouvé la réponse à l'adresse suivante stackoverflow.com/questions/13487987/ plus clair

198voto

Arjan Tijms Points 21682

La situation actuelle est en effet un peu confuse car il existe désormais plusieurs modèles de composants dans Java EE. Il s'agit de CDI , EJB3 y JSF Managed Beans .

CDI est le nouveau venu dans le quartier. Fonctionnalité des haricots CDI dependency injection , scoping et un event bus . Les beans CDI sont les plus flexibles en ce qui concerne l'injection et le scoping. Le bus d'événements est très léger et convient très bien aux applications Web les plus simples. En plus de cela, CDI expose également une fonctionnalité très avancée appelée portable extensions Il s'agit d'une sorte de mécanisme de plug-in permettant aux vendeurs de fournir des fonctionnalités supplémentaires à Java EE qui peuvent être disponibles sur toutes les implémentations (Glassfish, JBoss AS, Websphere, etc.).

EJB3 ont été mis à jour à partir de l'ancien modèle de composant EJB2. * et ont été les premiers beans de Java EE à être des beans gérés via une annotation. Fonctionnalités des beans EJB3 dependency injection , declarative transactions , declarative security , pooling , concurrency control , asynchronous execution y remoting .

L'injection de dépendances dans les beans EJB3 n'est pas aussi flexible que dans les beans CDI et les beans EJB3 n'ont pas de concept de scoping. Cependant, les beans EJB3 sont transactionnels et mutualisés par défaut. ** deux éléments très utiles que le CDI a choisi de laisser dans le domaine de l'EJB3. Les autres éléments mentionnés ne sont pas non plus disponibles dans CDI. EJB3 n'a pas de bus d'événements propre, mais il a un type spécial de bean pour écouter les messages : le message driven bean. Celui-ci peut être utilisé pour recevoir des messages du Java Messaging System ou de tout autre système disposant d'un adaptateur de ressources JCA. L'utilisation d'une messagerie complète pour des événements simples est beaucoup plus lourde que le bus d'événements CDI et EJB3 ne définit qu'une API d'écoute et non de production.

JSF Managed Beans existent dans Java EE depuis que JSF a été inclus. Ils présentent eux aussi dependency injection y scoping . JSF Managed Beans a introduit le concept de scoping déclaratif. À l'origine, les champs d'application étaient plutôt limités et dans la même version de Java EE où les beans EJB3 pouvaient déjà être déclarés via des annotations, les Managed Beans de JSF devaient encore être déclarés en XML. La version actuelle de JSF Managed Beans est finalement déclarée via une annotation et les champs d'application sont étendus avec un champ d'application de vue et la possibilité de créer des champs d'application personnalisés. La portée de vue, qui mémorise les données entre les requêtes à l'application même est une caractéristique unique de JSF Managed Beans.

En dehors de la portée de la vue, il y a encore très peu de choses pour les Managed Beans de JSF dans Java EE 6. L'absence de portée de vue dans CDI est regrettable, car sinon CDI aurait été un super ensemble parfait de ce que JSF Managed Beans offre. Mise à jour : En Java EE 7/JSF 2.2 a Compatible CDI @ViewScoped a été ajouté, faisant du CDI le super ensemble parfait. Mise à jour 2 : Dans JSF2.3, les beans gérés par JSF ont été dépréciés en faveur des beans gérés par CDI.

Avec EJB3 et CDI, la situation n'est pas aussi claire. Le modèle de composant et l'API d'EJB3 offrent un grand nombre de services que le CDI n'offre pas, de sorte qu'en règle générale, EJB3 ne peut être remplacé par le CDI. D'un autre côté, le CDI peut être utilisé en combinaison avec EJB3 - par exemple pour ajouter le support de la portée aux EJB.

Reza Rahman, membre du groupe d'experts et auteur d'une implémentation du CDI appelée CanDI, a fréquemment laissé entendre que les services associés au modèle de composant EJB3 peuvent être adaptés en tant qu'ensemble d'annotations CDI. Si cela devait se produire, tous les beans gérés dans Java EE pourraient devenir des beans CDI. Cela ne signifie pas que EJB3 disparaît ou devient obsolète, mais simplement que sa fonctionnalité sera exposée via CDI au lieu des annotations propres à EJB comme @Stateless et @EJB.

Mise à jour

David Blevins, de TomEE et OpenEJB, explique très bien les différences et les similitudes entre CDI et EJB sur son blog : CDI, quand sortir les EJBs

* Bien qu'il ne s'agisse que d'un incrément dans le numéro de version, les beans d'EJB3 étaient pour la plupart un type de bean complètement différent : un simple pojo qui devient un " bean géré " en appliquant une simple annotation, par opposition au modèle d'EJB2 où un descripteur de déploiement XML lourd et excessivement verbeux était requis pour chaque bean, en plus du fait que le bean devait implémenter diverses interfaces de composants extrêmement lourdes et pour la plupart sans signification.

** Les beans de session sans état sont généralement mis en commun, les beans de session avec état ne le sont généralement pas (mais ils peuvent l'être). Pour les deux types, le pooling est donc facultatif et la spécification EJB ne l'impose pas.

3 votes

Je suis un peu confus par vos déclarations selon lesquelles "les beans EJB3 n'ont pas de concept de scoping" et "EJB3 n'a pas de bus d'événements propre". Comment cela s'inscrit-il dans le cadre de David Blevin affirment que "les EJB sont Les haricots CDI et donc tous les avantages du CDI" ? Quelque chose a-t-il changé à cet égard entre le moment où vous avez écrit votre réponse et celui où David a écrit son billet de blog ?

5 votes

C'est à cause du concept, peut-être un peu déroutant, qu'il y a en fait pas vraiment des "beans CDI", mais il existe des services appliqués aux beans gérés. Pour les besoins de la discussion, les gens (et moi-même donc) les désignent de toute façon comme des "beans CDI". Avant CDI, les beans EJB n'avaient pas de scoping explicite. Comme David l'explique, Stateful est implicitement n'importe quelle portée (et donc aucune portée en particulier). Maintenant que le CDI est disponible, les beans EJB peuvent profiter des scopes fournis par le CDI. Sans la spécification CDI, donc en regardant uniquement la spécification EJB, il n'y a pas de scopes explicites.

1 votes

Pouvez-vous préciser ce que vous entendez par "il existe des services appliqués aux beans gérés" ? Cela signifie-t-il qu'il n'existe pas de haricot CDI ? Il s'agit simplement de fournir des fonctionnalités supplémentaires à un POJO - EJB - ou à un Managed Bean JSF ? Comme la possibilité d'utiliser l'annotation Inject dans un Managed Bean JSF ?

51voto

Maxym Points 7228

CDI : il s'agit de l'injection de dépendances. Cela signifie que vous pouvez injecter l'implémentation d'une interface n'importe où. Cet objet peut être n'importe quoi, il peut ne pas être lié à EJB. Ici est un exemple de la manière d'injecter un générateur aléatoire à l'aide de CDI. Il n'est pas question d'EJB. Vous utiliserez CDI lorsque vous voudrez injecter des services non-EJB, des implémentations différentes ou des algorithmes (vous n'avez donc pas du tout besoin d'EJB).
EJB : vous comprenez, et probablement vous êtes confus par @EJB qui vous permet d'injecter une implémentation dans votre service ou autre. L'idée principale est que la classe, où vous injectez, doit être gérée par le conteneur EJB. Il semble que CDI comprenne ce qu'est un EJB, donc dans un serveur conforme à Java EE 6, dans votre servlet vous pouvez écrire à la fois

@EJB EJBService ejbService;

et

@Inject EJBService ejbService;

c'est ce qui peut vous rendre confus, mais c'est probablement la seule chose qui constitue le pont entre EJB et CDI.

En ce qui concerne le CDI, vous pouvez injecter d'autres objets dans les classes gérées par le CDI (ils doivent simplement être créés par des frameworks compatibles CDI).

Ce que le CDI offre d'autre... Par exemple, vous utilisez Struts 2 comme framework MVC (juste un exemple), et vous êtes limité ici, même en utilisant EJB 3.1 - vous ne pouvez pas utiliser @EJB dans l'action Struts, elle n'est pas gérée par le conteneur. Mais lorsque vous ajoutez le plugin Struts2-CDI, vous pouvez y écrire @Inject pour la même chose (donc plus de recherche JNDI nécessaire). De cette façon, il renforce la puissance de l'EJB, mais comme je l'ai déjà mentionné, ce que vous injectez avec CDI - peu importe que ce soit lié à l'EJB ou non, et c'est là toute sa puissance.

PS. Mise à jour du lien vers l'exemple

0 votes

@EJB et @Inject sont-ils vraiment équivalents sur le plan fonctionnel ? Je pense que c'est le chevauchement des méthodes d'injection entre CDI et certains des autres acronymes de Java EE qui m'a troublé. Une lecture plus approfondie semble indiquer qu'il y a un espoir d'aligner les annotations.

0 votes

@Maxym Lorsque vous utilisez @ Inject, comment pouvez-vous vous assurer que le @ Stateless ou tout autre composant côté serveur de l'EJB utilise toujours les fonctionnalités comme le Pooling ou la concurrence qui est offerte par le conteneur. J'espère que cela n'est pas offert par CDI, n'est-ce pas ?

1 votes

@Bala : Le CDI n'offre pas de mise en commun... regardez à CDI avec ou sans EJB3.1 J'espère que cela répond à votre question.

-1voto

HA S Points 167

Albert Einstein : If you can't explain it simply, you don't understand it well enough

Ejbs et CDI sont assez simples à comprendre.

Ejbs :

  1. seront toujours annotés par des qualificatifs de portée, par exemple, @Stateless, @Stateful, @Request, etc.
  2. Les instances d'Ejbs sont contrôlées par le cadre Java EE et mises en commun. C'est le devoir du cadre EE de fournir les instances pour le consommateur.

@Stateless

 public class CarMaker(){
    public void createCar(Specification specs){
        Car car = new Car(specs);
    }
}

Le CarMaker est annoté avec une portée Ejbs spécifique, donc c'est un Ejb.

CDI :

  1. Non gérées entièrement par le cadre EE, les instances doivent être créées par vous-même.
  2. Il est toujours dépendant. Laissez-moi expliquer "dépendant" avec un exemple :

    class Specification { private String color; private String model; //- Getter and Setter }

El Specification est CDI, puisqu'elle n'est pas annotée avec les scopes Ejb et qu'elle doit être initialisée par votre code et non par le framework EE. Un point à noter ici est que puisque nous n'avons pas annoté la classe Specification elle est par défaut annotée par la classe @Dependent annotation.

@Dependent  <- By default added 
class Specification { ... }

Further reading: Vous devez étudier davantage l'annotation Ejbs scope et l'annotation CDI scope, ce qui clarifiera davantage le concept.

0 votes

Einstein a aussi dit : "Tout doit être rendu aussi simple que possible, mais pas plus simple". vous pouvez (devriez) remplacer "fait" par "expliqué" ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X