36 votes

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

J'ai la configuration suivante:

  • 1 OREILLE sur un GF contenant 2 EJB-Pots avec des composants EJB.
  • 1 la GUERRE sur un autre serveur Glassfish (=> d'autres JVM) contenant des composants web d'accéder aux composants EJB.

J'ai 2 EJB services aux entreprises dans chaque EJB-JAR 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 un explicite "InitialContext.de recherche" sur l'interface distante.

Dans mon OREILLE, je suis assez confus sur les meilleures pratiques pour l'injection, en termes de performances, de l'architecture, et ainsi de suite...

J'ai les questions suivantes:

  • Comme vous pouvez le voir, je l'ai déclaré à l'annotation "@Local" sur la mise en œuvre des services sans définition de l'interface locale. Est-il correct? Au moins je n'ai pas d'erreur lors du déploiement. Mais peut-être que je devrais utiliser le "@LocalBean" annotation à la place? Je suppose que le "@LocalBean" annotation permet simplement d'invoquer la mise en œuvre directement en tant que "Local" EJB, mais vous devez utiliser l'application dans votre code comme ceci:

    @Stateless @Local public class ServiceBImpl implémente ServiceBItf { @EJB privé ServiceAImpl serviceA; ... }

  • Quel est le meilleur moyen d'injecter un EJB dans un autre? Il fonctionne comme ceci:

    @Stateless @Local public class ServiceBImpl implémente ServiceBItf { @EJB privé ServiceAItf serviceA; ... }

Mais de ce que j'ai remarqué, 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éer une interface locale comme cela, le service n'est pas injectés via l'annotation "@Inject" mais est nulle:

@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 un local d'invocation. Ce qui m'amène à la question suivante: dans quels cas le "@"Local EJB invocation est recommandé (ou simplement)?

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

  • Pour chaque service, j'ai créer un "@Local" et un "@Distance" de l'interface.
  • De la GUERRE à EJB-JAR de l'OREILLE, faire une recherche JNDI de l'interface à distance.
  • D'EJB-JAR pour EJB-JAR, faire une injection via "@EJB" de l'interface locale.
  • Pour les deux services au sein de la même EJB-JAR, faire une injection via "@Inject" de l'interface locale.

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

22voto

jan groth Points 5071

Comme vous pouvez le voir, je l'ai déclaré à l'annotation "@Local" sur le service la mise en œuvre sans la définition de l'interface locale. Est-il correct?

Avec EJB 3.1, l'obligation pour les interfaces locales a été abandonné. Pas besoin de les écrire, sauf si vous explicitement besoin d'eux.

Quel est le meilleur moyen d'injecter un EJB dans un autre?

Couple de choses à écrire ici:

Avec Java EE 6, Java Enterprise a changé. Une nouvelle JSR définit un soi-disant managed bean (à ne pas confondre avec la JSF géré les haricots), comme une sorte de minimum de composants qui peuvent encore profiter du conteneur en termes de l'injection de dépendance et de gestion du cycle de vie. Cela signifie: Si vous disposez d'un composant et "juste" voulez utiliser DI et de laisser le conteneur de contrôle de son cycle de vie, vous n'avez pas besoin d'utiliser les Ejb pour elle. Vous finirez par utiliser les Ejb si - et seulement si - vous avez explicitement le besoin d'EJB fonctionnalités comme la gestion des transactions, la mise en commun, la passivation et le clustering.

Cela rend la réponse à votre question se déclinent en trois parties:

  1. Utiliser @Inject sur @EJB, la notion de CDI (un) fonctionne pour tous les haricots (ce qui inclut les Ejb) et (b) est dynamique et donc loin supérieure plus pure @EJB DI
  2. Êtes-vous sûr que vous avez besoin pour votre Ejb les composants?
  3. C'est certainement la peine d'avoir un coup d'oeil au CDI la documentation

0voto

maks Points 1770

@Inject d'annotation est utilisée pour les beans java(Pojo) tout en @EJB d'annotation est utilisée pour les enterprise java beans. Lorsqu'un conteneur injecter un ejb fournis par @EJB d'annotation à un autre bean il contrôle également que les ejb cycle de vie, effectue la mise en commun de stateless et ainsi de suite(quand bean qui va être injecté n'est pas déployé la référence sera nulle). Si vous utilisez @Inject d'annotation CDI mécanisme, il suffit de trouver et de créer une instance de la injecté des ressources comme avec l'opérateur new(si la mise en œuvre de l'interface qui va être injecté n'existe pas de référence sera nulle). Vous pouvez utiliser des qualificatifs avec @Inject d'annotation de choisir la mise en œuvre de la injecté de l'interface.

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