web-dev-qa-db-fra.com

Signification du mode de découverte du bean annoté dans CDI 1.1

Je migre une application vers Java EE 7 et je voudrais CDI 1.1. Mais je n'ai pas la signification de bean-discovery-mode="annotated". La spécification CDI 1.1 n'est pas très utile. Au moins, je n'ai trouvé aucun paragraphe utile. L'ai-je raté?

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 n'est pas en mesure d'injecter une instance dans le champ lc.

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

28
Oliver

En pratique, bean-discovery-mode="ALL" active l'analyse de toutes les classes dans une archive. C'est ce qu'on appelle une "archive explicite".

Omettre beans.xml ou définissant bean-discovery-mode="ANNOTATED", fait de l'archive une archive implicite. Dans ce cas, le conteneur recherchera les beans avec des types d'étendue annotés.

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

CDI ne peut gérer et injecter que des beans annotés avec un type de portée dans une archive implicite.

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

@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 beans.xml descripteur de déploiement 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 de l'inclusion de beans.xml ou pas. 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'empaquetage des applications CDI ici: http://docs.Oracle.com/javaee/7/tutorial/cdi-adv001.htm#CACDCFDE

34
Ian Evans

Lors de l'utilisation de bean-discovery-mode="annotated" uniquement les classes avec un bean définissant l'annotation sont découvertes . Toutes les autres classes sont ignorées. Tout type de portée est une annotation définissant le bean. Si un type de portée est déclaré sur une classe de bean, alors la classe de bean est censée avoir une annotation définissant le bean [spec]. La spécification 1.1 n'est pas complètement claire ici. Uniquement les classes avec un @NormalScope portée ou @Dependent une pseudo-portée est découverte, @javax.inject.Singleton et tous les autres @Scope (pseudo) étendues sont ignorées .

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

L'ensemble d'annotations définissant le bean contient:

  • @ApplicationScoped, @SessionScoped, @ConversationScoped et @RequestScoped,
  • tous les autres types de portée normaux,
  • @Interceptor et @Decorator annotations,
  • toutes les annotations de stéréotypes (c'est-à-dire les annotations annotées avec @Stereotype) et l'annotation @Dependent scope.
39
rmuller

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

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}

Si vous fournissez un fichier beans.xml avec:

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

Payara 4.1 traitera la classe SomeClass NON comme un bean CDI et n'injectera PAS le service EJB. Il 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 prévu. Pour que cela fonctionne, le fichier beans.xml devrait ressembler à ceci:

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

Il est étonnant que les deux serveurs d'applications les plus courants aient un comportement différent.

2
Ralph