我正在将应用程序迁移到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"
?
答案 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"....
令人惊讶的是,这两种最常见的应用程序服务器在行为上有所不同。