J'ai la configuration suivante:
J'ai 2 services commerciaux EJB dans chaque EJB-JAR de mon EAR, et ils sont tous développés comme ceci:
@Remote
public interface ServiceAItf {
...
}
@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
...
}
Dans ma GUERRE, j'accède aux composants EJB via un "InitialContext.lookup" sur l'interface distante.
Dans mon EAR, je suis assez confus quant aux meilleures pratiques d'injection, en termes de performances, d'architecture, etc.
J'ai les questions suivantes:
Comme vous pouvez le voir, j'ai déclaré l'annotation "@Local" sur l'implémentation du service sans définir l'interface locale. Est-ce correct? Au moins, je n'ai aucune erreur lors du déploiement. Mais je devrais peut-être utiliser le "@LocalBean" annotation à la place? Je suppose que le "@LocalBean" l'annotation permet simplement d'invoquer l'implémentation directement en tant que "Local" EJB, mais vous devez utiliser l'implémentation dans votre code comme ceci:
@Stateless @Local classe publique ServiceBImpl implémente ServiceBItf {@EJB private ServiceAImpl serviceA; ...}
Quelle est la meilleure façon d'injecter un EJB dans un autre? Cela fonctionne comme ceci:
@Stateless @Local classe publique ServiceBImpl implémente ServiceBItf {@EJB private ServiceAItf serviceA; ...}
Mais d'après ce que j'ai remarqué, le "serviceA" injecté est le proxy distant, alors qu'il se trouve dans la même JVM dans le même fichier EAR. Je suppose donc 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 cela ne fonctionne pas dans GF, j'ai l'exception suivante:
WELD-001408 Unsatisfied dependencies for type [...] ...
J'ai ensuite 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 "@Injecter" mais est nul:
@Local
public interface ServiceALocalItf {
...
}
J'ai lu beaucoup d'articles où il est fortement recommandé d'utiliser "@Injecter" au lieu de "@EJB" quand c'est pour une invocation locale. Cela m'amène à la question suivante: dans quel cas le "@Local" L'invocation EJB est recommandée (ou simplement utilisée)?
Après toute cette analyse, j'arrive à la conclusion suivante:
Qu'est-ce que tu en penses? Est-ce correct?
Comme vous pouvez le voir, j'ai déclaré l'annotation "@Local" sur l'implémentation du service sans définir l'interface locale. Est-ce correct?
Avec EJB 3.1, l'exigence d'interfaces locales a été supprimée. Pas besoin de les écrire sauf si vous en avez explicitement besoin.
Quelle est la meilleure façon d'injecter un EJB dans un autre?
Quelques choses à écrire ici:
Avec Java EE 6, Java Enterprise a changé. Un nouveau JSR définit un soi-disant bean géré (ne pas confondre avec les beans gérés JSF) comme une sorte de composant minimum qui peut toujours bénéficier du conteneur en termes d'injection de dépendances et de gestion du cycle de vie. Cela signifie: si vous avez un composant et "juste" voulez utiliser DI et laisser le conteneur contrôler son cycle de vie, vous n'avez pas besoin d'utiliser des EJB pour cela. Vous finirez par utiliser des EJB si - et uniquement si - vous avez explicitement besoin de fonctionnalités EJB telles que la gestion des transactions, la mise en commun, la passivation et le clustering.
Cela rend la réponse à votre question en trois parties:
@Inject
l'annotation est utilisée pour Java beans (POJO) tandis que @EJB
l'annotation est utilisée pour l'entreprise Java beans. Lorsqu'un conteneur injecte un ejb fourni par @EJB
annotation à un autre bean, il contrôle également le cycle de vie d'ejb, effectue la mise en pool des beans sans état, etc. (lorsque le bean qui va être injecté n'est pas déployé, la référence sera nulle). Si tu utilises @Inject
le mécanisme CDI d'annotation recherche et crée simplement 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 avec @Inject
annotation pour choisir une implémentation différente de l'interface injectée.