在CDI 1.1中注释的bean发现模式的含义

时间:2013-08-19 09:22:16

标签: dependency-injection cdi java-ee-7

我正在将应用程序迁移到Java EE 7并且想要CDI 1.1。但我没有得到bean-discovery-mode="annotated"的含义。该 CDI 1.1 specification不是很有帮助。至少我没有找到任何有用的段落。我错过了吗?

此示例与bean-discovery-mode="all"完美匹配,并注入LoggingClass的实例:

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

}

@Test
public class MMLoggerProducerIT extends Arquillian {

    @Inject private LoggingClass lc;

}

但是,如果我从bean-discovery-mode="all"更改为bean-discovery-mode="annotated",则容器无法将实例注入字段lc

如何正确注释LoggingClass以正确使用bean-discovery-mode="annotated"

3 个答案:

答案 0 :(得分:37)

仅使用bean-discovery-mode="annotated"类,其中 bean定义注释 are discovered。所有其他类都被忽略。 任何范围类型都是定义注释的bean。如果在bean类上声明了作用域类型,则说bean类具有定义注释的bean [spec]。 1.1规范在这里并不完全清楚。仅发现具有@NormalScope范围或@Dependent伪范围的类,@javax.inject.Singleton以及所有其他@Scope(伪)范围are ignored

请注意,“bean定义注释”的定义在CDI 1.2中已更改,现在定义得非常明确:

  

定义注释的bean集包含:

     
      
  • @ApplicationScoped,@ SessionScoped,@ ConversationScoped和@RequestScoped annotations,
  •   
  • 所有其他正常范围类型,
  •   
  • @Interceptor和@Decorator annotations,
  •   
  • 所有刻板印象注释(即用@Stereotype注释的注释),   和@Dependent范围注释。
  •   

答案 1 :(得分:34)

实际上,bean-discovery-mode="ALL"开启扫描存档中的所有类。这称为“显式存档”。

省略beans.xml或设置bean-discovery-mode="ANNOTATED"会使归档成为隐式归档。在这种情况下,容器将扫描带有注释范围类型的bean。

这解释了设置LoggingClass时未注入bean-discovery-mode="ANNOTATED"的原因。如Java EE 7教程中所述:

  

CDI只能在隐式存档中管理和注入使用范围类型注释的bean。

编辑:所以为了绝对清楚,您需要将范围类型添加到LoggingClass。所以像这样:

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

在Java EE 7和CDI 1.1中,我们删除了包含beans.xml部署描述符以打开存档CDI的要求,使CDI 1.1与部署描述符可选的大多数其他Java EE API一致。它还删除了包括beans.xml或不包括bean-discovery-mode的二进制开/关性质。您可以使用{{1}}中的设置控制容器扫描的文件。

请在此处查看有关打包CDI应用程序的JavaEE教程: http://docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm#CACDCFDE

答案 2 :(得分:2)

我也同意@rmuller的回答表格。但我想指出应用服务器Payara和Wildfly仍有不同的行为。 请参阅以下示例,其中包含普通的非作用域类但具有@EJB注入:

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}

如果您提供带有:

的beans.xml文件
 .... version="1.2" bean-discovery-mode="annotated"....

Payara 4.1会将类 SomeClass NOT视为CDI bean,并且不会注入服务EJB。 我很清楚它的行为如说明书中所述。

但Wildfly 10将该类视为CDI bean并注入不期望的服务EJB。为了使这个工作,beans.xml文件应如下所示:

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

令人惊讶的是,这两种最常见的应用程序服务器在行为上有所不同。