Signification du mode bean discovery annoté dans CDI 1.1

Je migre une application vers Java EE 7 et je voudrais CDI 1.1. Mais je ne comprends pas le sens de bean-discovery-mode="annotated". Le CDI 1.1 spécification n'est pas très utile. Au moins, je n'ai trouvé aucun paragraphe utile. Ai-je manquer?

Cet exemple fonctionne parfaitement avec bean-discovery-mode="all" et injecte une instance de LoggingClass:

public class LoggingClass {
    public Logger logger = Logger.getLogger("ALOGGER");

}

@Test
public class MMLoggerProducerIT extends Arquillian {

    @Inject private LoggingClass lc;

}

Mais si je change de bean-discovery-mode="all" à bean-discovery-mode="annotated" le conteneur ne peut pas injecter une instance dans le champ lc.

Comment dois-je annoter LoggingClass pour utiliser bean-discovery-mode="annotated" correctement?

21
demandé sur Oliver 2013-08-19 13:22:15

3 réponses

En pratique, {[1] } active l'analyse de toutes les classes d'une archive. C'est ce qu'on appelle une "archive explicite".

En omettant beans.xml ou en définissant bean-discovery-mode="ANNOTATED", l'archive devient une archive implicite. Dans ce cas, le conteneur recherchera les beans avec des types de portée annotés.

Ceci explique pourquoi LoggingClass n'est pas injecté lorsque vous définissez bean-discovery-mode="ANNOTATED". Comme documenté dans le tutoriel Java EE 7:

CDI ne peut gérer et injecter que des beans annotés avec un implicite de l'archive.

Edit: donc, juste pour être absolument clair, vous devez ajouter un type de portée à LoggingClass. Donc quelque chose comme ceci:

@SessionScoped
public class LoggingClass {
    public Logger logger = Logger.getLogger("ALOGGER");
}

Dans Java EE 7 et CDI 1.1, nous avons supprimé l'exigence d'inclure le descripteur de déploiement beans.xml pour activer CDI pour une archive, alignant CDI 1.1 avec la plupart des autres API Java EE où les descripteurs de déploiement sont facultatifs. Il a également supprimé la nature binaire on/off d'inclure beans.xml ou non. Vous pouvez contrôler quels fichiers sont analysés par le conteneur avec les paramètres dans bean-discovery-mode.

Voir le tutoriel JavaEE sur l'emballage des applications CDI ici: http://docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm#CACDCFDE

31
répondu Ian Evans 2015-03-20 13:41:33

Lorsque vous utilisez bean-discovery-mode="annotated" uniquement des classes avec une annotation de définition de bean sont découverts . Toutes les autres classes sont ignorées. tout type de portée est une annotation de définition de bean. Si un type de portée est déclaré sur une classe bean, alors la classe bean est dite avoir une annotation de définition de bean [spec]. La spécification 1.1 n'est pas complètement claire ici. Seules les classes avec une portée @NormalScope ou une pseudo-portée @Dependent sont découvertes, @javax.inject.Singleton et toutes les autres étendues @Scope (pseudo) sont ignorées .

Notez que la définition d'une "annotation de définition de bean" a changé dans CDI 1.2 et est maintenant très bien définie:

L'ensemble des annotations définissant les beans contient:

  • @ApplicationScoped, @SessionScoped, @ConversationScoped et @ RequestScoped annotations,
  • tous les autres types de portée normale,
  • @Interceptor et @Décorateur annotations,
  • toutes les annotations stéréotypées (c'est-à-dire les annotations annotées avec @Stereotype), et la @ Annotation de portée dépendante.
34
répondu rmuller 2015-03-20 15:04:19

Je suis également d'accord avec le formulaire de réponse @rmuller. Mais je tiens à souligner qu'il existe encore un comportement différent sur les serveurs D'applications Payara et Wildfly. Voir l'exemple suivant avec une classe normale non étendue mais ayant une injection @EJB:

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}

Si vous fournissez un haricots.fichier xml avec:

 .... version="1.2" bean-discovery-mode="annotated"....

Payara 4.1 traitera la classe SomeClass pas comme un bean CDI et n'injectera pas le service EJB. Ceci est clair pour moi qu'il se comporte comme indiqué dans la spécification.

Mais Wildfly 10 traite la classe comme un bean CDI et injecte le service EJB qui n'est pas attendu. Pour faire fonctionner les haricots.le fichier xml devrait ressembler à ceci:

 .... version="1.2" bean-discovery-mode="all"....

Il est étonnant que les deux serveurs d'applications les plus courants soient différents ici dans le comportement.

1
répondu Ralph 2018-03-14 13:42:05