web-dev-qa-db-fra.com

Comment CDI et EJB se comparent-ils? interagir?

J'ai du mal à comprendre comment les deux interagissent et où se situe la frontière entre eux. 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 pu trouver une liste complète pour les deux avec de brèves descriptions. Je ne sais pas si cela aiderait à clarifier comment ils diffèrent ou où ils se chevauchent.

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

103
Tim

CDI - il s'agit de l'injection de dépendance. Cela signifie que vous pouvez injecter l'implémentation de l'interface n'importe où. Cet objet peut être n'importe quoi, il ne peut pas être lié à EJB. Ici est un exemple de la façon d'injecter un générateur aléatoire en utilisant CDI. Il n'y a rien à propos d'EJB. Vous allez utiliser CDI lorsque vous souhaitez injecter des services non EJB, différentes implémentations ou algorithmes (vous n'avez donc pas besoin du tout d'EJB).
EJB que vous comprenez, et vous êtes probablement dérouté par l'annotation @EJB - cela vous permet d'injecter l'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 l'EJB, donc dans Java EE 6, dans votre servlet, vous pouvez écrire les deux

@EJB EJBService ejbService;

et

@Inject EJBService ejbService;

c'est ce qui peut vous prêter à confusion, mais c'est probablement la seule chose qui est le pont entre EJB et CDI.

Lorsque nous parlons de CDI, vous pouvez injecter d'autres objets dans des classes gérées CDI (ils doivent simplement être créés par des frameworks compatibles CDI).

Quoi d'autre CDI offre ... 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 l'annotation @EJB dans l'action Struts, il n'est pas géré par récipient. Mais lorsque vous ajoutez le plug-in Struts2-CDI, vous pouvez y écrire l'annotation @Inject pour la même chose (donc plus de recherche JNDI nécessaire). De cette façon, il améliore la puissance EJB. Mais comme je l'ai mentionné précédemment, ce que vous injectez avec CDI - peu importe s'il est lié à EJB ou non, et c'est sa puissance

PS. lien mis à jour vers l'exemple

48
Maxym

C'est actuellement un peu déroutant car il existe maintenant plusieurs modèles de composants dans Java EE. Ils sont [~ # ~] cdi [~ # ~], EJB3 et JSF Managed Beans.

[~ # ~] cdi [~ # ~] est le nouvel enfant du bloc. Fonctionnalité des beans CDI dependency injection, scoping et un event bus. Les haricots CDI sont les plus flexibles en termes d'injection et de cadrage. Le bus d'événements est très léger et convient parfaitement aux applications Web les plus simples. En plus de cela, CDI expose également une fonctionnalité très avancée appelée portable extensions, qui est une sorte de mécanisme de plug-in permettant aux fournisseurs de fournir des fonctionnalités supplémentaires à Java EE qui peut être mis à disposition sur toutes les implémentations (Glassfish, JBoss AS, Websphere, etc.).

EJB3 les beans ont été modifiés par rapport à l'ancien modèle de composant EJB2 hérité* et ont été les premiers beans de Java EE à gérer en tant que beans via une annotation. Les beans EJB3 disposent de dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous execution et remoting.

L'injection de dépendance dans les beans EJB3 n'est pas aussi flexible que dans les beans CDI et les beans EJB3 n'ont pas de concept de portée. Cependant, les beans EJB3 sont transactionnels et regroupés par défaut**, deux choses très utilisables que CDI a choisi de laisser dans le domaine des EJB3. Les autres éléments mentionnés ne sont pas non plus disponibles dans CDI. EJB3 n'a cependant pas de bus d'événements, mais il a un type spécial de bean pour écouter les messages; le bean géré par message. Cela peut être utilisé pour recevoir des messages du système de messagerie Java ou de tout autre système doté d'un adaptateur de ressources JCA. L'utilisation de la messagerie complète pour les événements simples est beaucoup plus lourde que le bus d'événements CDI et EJB3 définit uniquement un écouteur, pas une API de producteur.

JSF Managed Beans existe depuis Java EE depuis que JSF a été inclus. Ils comportent également dependency injection et scoping. JSF Managed Beans a introduit le concept de portée déclarative. À l'origine, les portées étaient plutôt limitées et dans la même version de Java EE où les beans EJB3 pouvaient déjà être déclarés via des annotations, les beans gérés JSF devaient encore être déclarés en XML. La version actuelle de JSF Managed Les beans sont également finalement déclarés via une annotation et les étendues sont étendues avec une étendue de vue et la possibilité de créer des étendues personnalisées. L'étendue de vue, qui se souvient des données entre les demandes à la page même est unique fonction des JSF Managed Beans.

Hormis la portée de la vue, il y a très peu de choses à faire pour les beans gérés JSF dans Java EE 6. La portée de la vue manquante dans CDI est regrettable, car sinon CDI aurait été un super ensemble parfait de l'offre de JSF Managed Beans. Update: In Java EE 7/JSF 2.2 a CDI compatible @ViewScoped a été ajouté, ce qui fait du CDI ce super ensemble parfait. Update 2: Dans JSF2.3, les beans gérés JSF ont été déconseillés au profit des beans gérés par CDI.

Avec EJB3 et CDI, la situation n'est pas aussi nette. Le modèle de composant EJB3 et l'API offrent de nombreux services que CDI n'offre pas, donc généralement EJB3 ne peut pas être remplacé par CDI. D'autre part, CDI peut être utilisé en combinaison avec EJB3 - par ex. ajout de la prise en charge de la portée aux EJB.

Reza Rahman, membre du groupe d'experts et implémenteur d'une implémentation CDI appelée CanDI, a souvent laissé entendre que les services associés au modèle de composant EJB3 peuvent être modifié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 de via. Les propres annotations d'EJB comme @Stateless et @EJB.

Mettre à jour

David Blevins de la renommée 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 EJB

* Bien que ce ne soit qu'un incrément dans le numéro de version, les beans 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 simple, par rapport au modèle dans EJB2 où un poids lourd et un descripteur de déploiement XML trop verbeux était requis pour chaque bean, en plus du bean étant requis pour implémenter diverses interfaces de composants extrêmement lourdes et pour la plupart sans signification.

** Les beans session sans état sont généralement regroupés, les beans session avec état généralement pas (mais ils peuvent l'être). Pour les deux types, la mise en commun est donc facultative et la spécification EJB ne la rend pas obligatoire dans les deux cas.

186
Arjan Tijms

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

Les Ejbs et CDI sont assez simples à comprendre.

Ejbs:

  1. Sera toujours annoté par les qualificateurs de portée, par exemple, @Stateless, @Stateful, @Request etc.
  2. Les instances d'Ejbs sont contrôlées par le cadre Java EE et regroupées. Il est du devoir du cadre EE de fournir les instances au 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 Ejb

CDI:

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

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

La classe Specification est CDI, car elle n'est pas annotée avec les étendues Ejb et cela doit également être initialisé 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 @Dependent annotation.

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

Further reading: Vous devez étudier davantage entre l'annotation de portée Ejbs et l'annotation de portée CDI, ce qui clarifiera davantage le conceptl

0
HA S