web-dev-qa-db-fra.com

Quelle est la différence entre @Inject et @EJB

J'apprends actuellement les nouveaux modèles de composants Java EE 6 et je suis confondu avec le dernier mécanisme d'injection de dépendances. Voici donc mes questions:

1) Quelle est la différence entre @Inject et @EJB

2) Si j'ai un POJO simple qui contient un autre POJO (dont l'un est le code DAO), quel serait le meilleur choix: @Inject ou @EJB?

Puis-je mélanger @Inject et @EJB?

Un exemple serait:

  • ClassA implémente InterfaceA et possède une instance de ClassA_Adaptor

  • ClassA_Adaptor implémente InterfaceAB et a une instance de ClassB

  • ClassB implémente InterfaceB et a une instance de ClassB_Adaptor et une instance DAO_ClassB

  • ClassB_Adaptor implémente InterfaceB et a une instance de ClassC

  • ClassC implémente InterfaceBC et possède une instance de WebService_ClassC

  • DAO_ClassB utilisera JPA 2.0 (@PersistenceContext)

Je voudrais tous les injecter, y compris le DAO et le WebService.

3) Est-ce une mauvaise approche de n'utiliser transactionnel que pour certaines opérations mais pas pour toutes?

Par exemple: Certaines méthodes de DAO_ClassB sont votre requête typique, tandis que d'autres méthodes sont des méthodes "d'écriture". Est-il mauvais de ne pas encapsuler les méthodes "LIRE" avec la transaction?

À ma connaissance, le DAO_ClassB peut être encapsulé avec une transaction en utilisant @EJB (injectez le DAO_ClassB et rendez toutes les méthodes transactionnelles). Comment puis-je le contrôler?

Désolé si certaines des questions prêtent à confusion, car je ne connais que les éléments du nouveau modèle de composant Java EE 6).

37
xandross
  1. @EJB injecte uniquement des EJB, mais @Inject peut être utilisé pour injecter des POJO plutôt que des EJB. Cependant, @Inject requiert que votre archive soit un BDA (contient beans.xml pour EE 6, ou implicitement dans EE 7). @Inject possède également des capacités spécifiques à CDI supplémentaires (étendues, intercepteurs, etc.), mais ces capacités entraînent des frais supplémentaires. Les serveurs d'applications prennent en charge la spécification des liaisons @EJB afin qu'un déployeur puisse choisir l'EJB cible, mais @Inject permet uniquement au développeur de l'application de choisir l'EJB cible (et il doit exister dans l'application).

  2. Si la cible n'est pas un EJB, vous ne devez pas utiliser @EJB.

  3. Cela dépend si vous effectuez plusieurs requêtes interdépendantes, puis essayez de prendre des décisions commerciales. Vous devez comprendre les niveaux d'isolement et les prendre en considération, même pour les opérations en lecture seule.

31
Brett Kail

De Adam Biens Weblog:

Vous pouvez utiliser les deux annotations pour injecter des EJB. Commencez avec @Inject et si vous rencontrez des problèmes, passez à @EJB.

@Inject does not have any methods / attributes--it is just a plain annotation:


@Target(value = {ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface Inject {
}

D'un autre côté, l'annotation @EJB vous permet de transmettre des informations supplémentaires, qui pourraient être utiles pour référencer des EJB distants, ou des EJB qui ne peuvent pas être simplement injectés dans le style "Convention over Configuration":

@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface EJB {

    public String name() default "";

    public String beanName() default "";

    public Class beanInterface() default Object.class;

    public String mappedName() default "";
}
10
  1. @Inject est plus général que EJB et fait partie de la spécification CDI. Donc, si vous souhaitez utiliser @Inject, vous devez en avoir une implémentation sur votre serveur.

  2. Pour les POJO (pas les EJB), vous devez utiliser @Inject.

6
victor herrera