Dois-je utiliser @EJB ou @Inject

148

J'ai trouvé cette question: quelle est la différence entre @Inject et @EJB mais je n'ai pas été plus sage. Je n'ai jamais fait Java EE auparavant et je n'ai pas d'expérience avec l'injection de dépendances, donc je ne comprends pas ce que je dois utiliser?

@EJB est-il une ancienne méthode d'injection? L'injection est-elle effectuée par le conteneur EJB lors de l'utilisation de cette annotation tout en utilisant @Inject utiliser le nouveau framework CDI? Est-ce la différence et devrais-je utiliser @Inject au lieu de @EJB si tel est le cas?

Lucky Luke
la source

Réponses:

178

Le @EJBest utilisé pour injecter uniquement des EJB et est disponible depuis un certain temps maintenant. @Injectpeut injecter n'importe quel bean géré et fait partie de la nouvelle spécification CDI (depuis Java EE 6).

Dans les cas simples, vous pouvez simplement passer @EJBà @Inject. Dans des cas plus avancés (par exemple, lorsque vous dépendez fortement @EJBdes attributs de comme beanName, lookupou beanInterface) que pour utiliser, @Injectvous devez définir un @Producerchamp ou une méthode.

Ces ressources peuvent être utiles pour comprendre les différences entre @EJBet @Produceset comment en tirer le meilleur parti:

Le blog d'Antonio Goncalves:
CDI Partie I
CDI Partie II
CDI Partie III

Documentation JBoss Weld:
CDI et l'écosystème Java EE

StackOverflow:
Injectez le bean @EJB en fonction des conditions

Piotr Nowicki
la source
4
pourquoi @EJBfonctionne l'injection circulaire (un bean singleton et un autre bean ayant besoin d'une référence l'un à l'autre)? (en référence à ma réponse ci-dessous - je ne suis pas sûr si je fais la bonne chose en passant à @EJB)
nécromancien
2
car vous n'injectez pas l'implémentation, mais un proxy qui s'interpose sur l'implémentation. à cause de cela, vous bénéficiez des avantages de la "liaison tardive" et d'autres fonctionnalités de conteneur.
lui
33

@Injectpeut injecter n'importe quel bean, alors que @EJBne peut injecter que des EJB. Vous pouvez utiliser l'un ou l'autre pour injecter des EJB, mais je préfère @Injectpartout.

Bozho
la source
1
Qu'est-ce qui fait exactement l'injection lorsque nous utilisons @Inject? Le conteneur JavaEE? Peut-il injecter des POJO?
Koray Tugay
3
avec CDI c'est le conteneur CDI (livré dans le conteneur JavaEE)
Bozho
16

Mise à jour: cette réponse peut être incorrecte ou obsolète. Veuillez consulter les commentaires pour plus de détails.

Je suis passé de @Injectà @EJBcar @EJBpermet l'injection circulaire alors que le @Injectvomit dessus.

Détails: j'avais besoin @PostConstructd'appeler une @Asynchronousméthode, mais cela se ferait de manière synchrone. La seule façon de faire l'appel asynchrone était d'avoir l'appel d'origine à une méthode d'un autre bean et de lui faire rappeler la méthode du bean d'origine. Pour ce faire, chaque grain avait besoin d'une référence à l'autre - donc circulaire. @Injecta échoué pour cette tâche alors qu'il @EJBtravaillait.

nécromancien
la source
@MartijnBurger Je n'ai pas le code à portée de main, ni un environnement Java EE à portée de main. Créez simplement 2 classes Java et @Injectles dans les champs publics de l'autre. Si cela fonctionne, ma réponse est fausse. Si cela ne fonctionne pas, ma réponse est correcte jusqu'à présent. Ensuite, changez le @Injecten @EJB(et annotez éventuellement les classes elles-mêmes? J'oublie.). Ensuite, l'injection mutuelle cyclique devrait fonctionner correctement. C'est pourquoi je suis passé de @Injectà @EJB. J'espère que cela a du sens.
nécromancien
J'ai créé deux pojo et injecté les pojo l'un dans l'autre. Fonctionne sans problème dans ma configuration (WildFly 8.2 = CDI 1.2)
Martijn Burger
1
Merci @MartijnBurger, je vais le confirmer, et en attendant ajouter une note de prudence à ma réponse.
nécromancien
Vous ne savez pas exactement ce que vous vouliez réaliser, mais cela fait probablement exactement ce que vous vouliez et sans dépendance circulaire. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Les événements CDI asynchrones pourraient également être une solution plus propre (selon les besoins).
JanM
12

Voici une bonne discussion sur le sujet. Gavin King recommande @Inject sur @EJB pour les EJB non distants.

http://www.seamframework.org/107780.lace

ou

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

Re: Injecter avec @EJB ou @Inject?

  1. Nov 2009, 20:48 Amérique / New_York | Lien Gavin King

Cette erreur est très étrange, car les références locales d'EJB doivent toujours être sérialisables. Bug dans le poisson-verre, peut-être?

En gros, @Inject est toujours meilleur, puisque:

it is more typesafe,
it supports @Alternatives, and
it is aware of the scope of the injected object.

Je déconseille l'utilisation de @EJB, sauf pour déclarer des références à des EJB distants.

et

Re: Injecter avec @EJB ou @Inject?

  1. Nov 2009, 17:42 Amérique / New_York | Lien Gavin King

    Cela signifie-t-il mieux @EJB avec les EJB distants?

Pour un EJB distant, nous ne pouvons pas déclarer des métadonnées comme des qualificatifs, @Alternative, etc. sur la classe de bean, car le client n'aura tout simplement pas accès à ces métadonnées. De plus, certaines métadonnées supplémentaires doivent être spécifiées dont nous n'avons pas besoin pour le cas local (nom JNDI global ou autre). Donc, tout cela doit aller ailleurs: à savoir la déclaration @Produces.

John Manko
la source
1
Bien que cela puisse théoriquement répondre à la question, il serait préférable d'inclure ici les parties essentielles de la réponse et de fournir le lien pour référence. De cette façon, cette réponse serait précieuse même maintenant lorsque le lien est mort.
Mifeet
4

Il peut également être utile de comprendre la différence en terme d'identité du bean de session lors de l'utilisation de @EJB et @Inject. Selon les spécifications, le code suivant sera toujours true:

@EJB Cart cart1;
@EJB Cart cart2;
 if (cart1.equals(cart2)) { // this test must return true ...}

Utiliser @Inject au lieu de @EJB, ce n'est pas la même chose.

voir aussi l' identité des beans session sans état pour plus d'informations

Ken
la source
0

L'injection existait déjà dans Java EE 5 avec les annotations @Resource, @PersistentUnit ou @EJB, par exemple. Mais il était limité à certaines ressources (source de données, EJB ...) et à certains composants (Servlets, EJB, backing bean JSF ...). Avec CDI, vous pouvez injecter presque n'importe quoi n'importe où grâce à l'annotation @Inject.

javierZanetti
la source