@Inject, @EJB, @Local, @Remote, @LocalBean, etc...: confus?

j'ai la configuration suivante:

  • 1 oreille sur un GF contenant 2 bocaux EJB avec des composants EJB.
  • 1 GUERRE sur un autre serveur Glassfish ( = > autres JVM) contenant des composants web accédant aux composants EJB.

j'ai 2 services D'affaires EJB dans chaque pot EJB de mon oreille, et ils sont tous développés comme ceci:

@Remote
public interface ServiceAItf {
    ...
}

@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
    ...
}

Dans ma GUERRE, je accéder aux composants EJB via explicite " Contexteinitial.lookup" sur l'interface distante.

dans mon oreille, je suis assez confus au sujet de la meilleure pratique pour l'injection, en termes de performance, d'architecture, et ainsi de suite...

j'ai les questions suivantes:

  • Comme vous pouvez le voir, je l'ai déclaré à l'annotation "@Local" sur l'implémentation du service sans définir l'interface locale. Est-il correct? Au moins je n'ai pas d'erreur lors du déploiement. Mais peut-être que je doit utiliser les "@LocalBean" annotation à la place? Je suppose que la "@LocalBean" annotation permet simplement d'invoquer l'implémentation directement comme un "Local" EJB, mais vous devez utiliser l'application dans votre code comme ceci:

    @apatrides @Local public class ServiceBImpl implements ServiceBItf { @EJB privé ServiceAImpl serviceA; ... }

  • Quelle est la meilleure façon d'injecter une EJB dans un autre? Il fonctionne comme ceci:

    @apatrides @Local public class ServiceBImpl implements ServiceBItf { @EJB privé ServiceAItf serviceA; ... }

<!-Mais d'après ce que j'ai vu, le "serviceA" injecté est le proxy distant, alors qu'il est dans la même JVM dans le même fichier EAR. Donc je suppose qu'il y aura un impact sur les performances. C'est pourquoi j'ai essayé d'injecter le service comme ceci:

@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
    @Inject
    private ServiceAItf serviceA;
    ...
}

Mais il ne fonctionne pas dans GF, j'ai l'exception suivante:

WELD-001408 Unsatisfied dependencies for type [...] ...

j'ai alors essayé de créer une interface locale, et l'injection via l'annotation "@Inject" fonctionne lorsque les deux services

même si je crée une interface locale comme celle-ci, le service n'est pas injecté via l'annotation "@Inject" mais est null:

@Local
public interface ServiceALocalItf {
    ...
}

j'ai lu beaucoup d'articles où il est fortement recommandé d'utiliser "@Inject" au lieu de "@EJB" quand c'est pour une invocation locale. Cela m'amène à la question suivante: dans quel cas le "@Local" EJB invocation est recommandé (ou simplement)?

Après toute cette analyse, j'en viens à la conclusion suivante:

  • pour chaque service, je crée un "@Local" et "@Remote" interface.
  • de la guerre à L'EJB-JAR de L'oreille, faites une recherche JNDI sur l'interface distante.
  • de EJB-JAR à EJB-JAR, faites une injection via "@EJB" à l'interface locale.
  • pour deux services dans le même EJB-JAR, faites une injection via "@Inject" à l'interface locale.

Qu'en pensez-vous? Est-il correct?

35
demandé sur Blaise Gosselin 2011-09-09 17:21:23

2 réponses

comme vous pouvez le voir, j'ai déclaré l'annotation "@Local" sur le service mise en œuvre sans définir l'interface locale. Est-il correct?

avec EJB 3.1, l'exigence d'interfaces locales a été supprimée. Pas besoin de les écrire, sauf si vous explicitement besoin d'eux.

Quelle est la meilleure façon d'injecter une EJB dans une autre?

deux choses à écrire ici:

avec Java EE 6, Java Enterprise a changé. Une nouvelle JSR définit un soi-disant gestion des haricots (ne pas confondre avec JSF managed beans) comme une sorte de Composant minimum qui peut encore bénéficier du container en termes d'injection de dépendances et de gestion du cycle de vie. Cela signifie: Si vous avez un composant et" juste " vouloir utiliser DI et laisser le container contrôler son cycle de vie, vous ne faites pas besoin pour utiliser les Ejb. Vous finirez par utiliser EJBs si - et seulement si-vous avez explicitement besoin de fonctionnalités EJB comme traitement des transactions, mise en commun, passivation et regroupement.

Cela fait que la réponse à votre question vient en trois parties:

  1. utiliser @Inject over @EJB, le concept de CDI (a) fonctionne pour tous les managés fèves (ce qui comprend EJBs) et (b) est stateful et donc loin supérieur à pur @EJB DI
  2. Êtes-vous sûr que vous avez besoin D'EJBs pour votre les composants?
  3. C'est certainement la peine de regarder le CDI documentation
21
répondu jan groth 2013-06-16 09:42:21

@Inject l'annotation est utilisée pour Java beans(POJOs) tandis que @EJB l'annotation est utilisée pour enterprise java beans. Quand un conteneur injecte une ejb fournie par @EJB annotation à un autre haricot il contrôle également que le cycle de vie d'ejb, effectue la mise en commun pour les haricots apatrides et ainsi de suite (lorsque le haricot qui va être injecté n'est pas déployé la référence sera nulle). Si vous utilisez @Inject annotation mécanisme CDI il suffit de trouver et de créer une instance de ressource injectée comme avec un nouvel opérateur(si l'implémentation de l'interface qui va être injectée n'existe pas la référence sera nulle). Vous pouvez utiliser des qualificatifs @Inject annotation pour choisir une implémentation différente de l'interface injectée.

0
répondu maks 2011-09-09 18:22:39