Dependency injection CDI 1.1中注释的bean发现模式的含义
我正在将一个应用程序迁移到JavaEE7,并希望迁移到CDI1.1。但是我不明白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
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类中添加注释吗?