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

Dependency injection CDI 1.1中注释的bean发现模式的含义,dependency-injection,cdi,java-ee-7,Dependency Injection,Cdi,Java Ee 7,我正在将一个应用程序迁移到JavaEE7,并希望迁移到CDI1.1。但是我不明白bean discovery mode=“annotated”的含义。这个 这不是很有帮助。至少我没有找到任何有用的段落。我错过了吗 此示例与bean discovery mode=“all”完美结合,并注入了LoggingClass的一个实例: 公共类日志类{ public Logger=Logger.getLogger(“ALOGGER”); } @试验 公共类MMLoggerProducerIT扩展了Arqui

我正在将一个应用程序迁移到JavaEE7,并希望迁移到CDI1.1。但是我不明白
bean discovery mode=“annotated”
的含义。这个 这不是很有帮助。至少我没有找到任何有用的段落。我错过了吗

此示例与
bean discovery mode=“all”
完美结合,并注入了
LoggingClass的一个实例:

公共类日志类{
public Logger=Logger.getLogger(“ALOGGER”);
}
@试验
公共类MMLoggerProducerIT扩展了Arquillian{
@注入私有日志类lc;
}
但是如果我从
bean discovery mode=“all”
更改为
bean discovery mode=“annotated”
则容器无法将实例注入字段
lc


如何注释
LoggingClass
才能正确使用
bean discovery mode=“annotated”

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

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

这解释了当您设置
bean discovery mode=“ANNOTATED”
时,
LoggingClass
没有被注入的原因。如Java EE 7教程中所述:

CDI只能在隐式归档中管理和注入带范围类型注释的bean

编辑:为了绝对清楚,您需要向
LoggingClass
添加一个范围类型。比如说:

@SessionScoped
public class LoggingClass {
    public Logger logger = Logger.getLogger("ALOGGER");
}
 .... version="1.2" bean-discovery-mode="all"....
在JavaEE7和CDI1.1中,我们删除了包含
beans.xml
部署描述符的要求,以打开存档的CDI,从而使CDI1.1与大多数其他JavaEEAPI保持一致,部署描述符是可选的。它还删除了是否包含
beans.xml
的二进制开/关特性。您可以使用
bean发现模式中的设置控制容器扫描哪些文件

请参见此处有关打包CDI应用程序的JavaEE教程:

当使用
bean发现模式=“annotated”
时,仅使用带有bean定义注释的类。忽略所有其他类。任何范围类型都是定义bean的注释。如果在一个bean类上声明了一个作用域类型,那么该bean类被称为具有一个bean定义注释[spec]。1.1规范在这里并不完全清楚。只发现具有
@NormalScope
作用域或
@Dependent
伪作用域的类、
@javax.inject.Singleton
和所有其他
@scope
(伪)作用域

请注意,“bean定义注释”的定义在CDI 1.2中发生了更改,现在定义得非常好:

定义bean的注释集包含:

  • @ApplicationScoped、@SessionScoped、@ConversationScoped和@RequestScoped注释
  • 所有其他正常范围类型
  • @拦截器和@Decorator注释
  • 所有原型注释(即用@stereotype注释的注释), 和@Dependent范围注释

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

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}
如果提供的beans.xml文件包含:

 .... version="1.2" bean-discovery-mode="annotated"....
Payara 4.1不会将类SomeClass视为CDIBean,也不会注入服务EJB。 我很清楚,它的行为符合规范中的规定

但是Wildfly 10将该类视为CDIBean,并注入了不期望的服务EJB。要使其正常工作,beans.xml文件应如下所示:

@SessionScoped
public class LoggingClass {
    public Logger logger = Logger.getLogger("ALOGGER");
}
 .... version="1.2" bean-discovery-mode="all"....

令人惊讶的是,这两个最常见的应用服务器在行为上是不同的

我只是猜测,但我认为“@Named”或“@ManagedBean”可能是候选项?@Mike_Braun Named只会在EL上下文中公开一个bean,但不会给它一个作用域。ManagedBean是一个JSF注释,CDI引擎将忽略它。如果没有
beans.xml
,拦截器和装饰器是如何注册和排序的?有什么办法吗?@nosuchnick拦截器可以通过注释使用
@Interceptors
@Priority
订购,如前所述。它是否描述了如何使@products工作?我必须在Factory类中添加注释吗?