Meaning of bean discovery mode annotated in CDI 1.1

拟墨画扇 提交于 2019-12-17 07:30:46

问题


I am migrating an application to Java EE 7 and would like to CDI 1.1. But I don't get the meaning of bean-discovery-mode="annotated". The CDI 1.1 specification is not very helpful. At least I have not found any useful paragraph. Did I miss it?

This example runs perfectly with bean-discovery-mode="all" and injects an instance of LoggingClass:

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

}

@Test
public class MMLoggerProducerIT extends Arquillian {

    @Inject private LoggingClass lc;

}

But if I change from bean-discovery-mode="all" to bean-discovery-mode="annotated" the container is not able to inject an instance into the field lc.

How do I have to annotate LoggingClass to use bean-discovery-mode="annotated" correctly?


回答1:


As a practical matter, bean-discovery-mode="ALL" turns on scanning of all classes in an archive. This is called an "explicit archive".

Omitting beans.xml, or setting bean-discovery-mode="ANNOTATED", makes the archive an implicit archive. In this case, the container will scan for beans with annotated scope types.

This explains why LoggingClass isn't injected when you set bean-discovery-mode="ANNOTATED". As documented in the Java EE 7 Tutorial:

CDI can only manage and inject beans annotated with a scope type in an implicit archive.

Edit: so just to be absolutely clear, you need to add a scope type to LoggingClass. So something like this:

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

In Java EE 7 and CDI 1.1, we removed the requirement to include the beans.xml deployment descriptor to turn on CDI for an archive, bringing CDI 1.1 in line with most other Java EE APIs where deployment descriptors are optional. It also removed the binary on/off nature of including beans.xml or not. You can control which files are scanned by the container with the settings in bean-discovery-mode.

See the JavaEE tutorial on packaging CDI applications here: http://docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm#CACDCFDE




回答2:


When using bean-discovery-mode="annotated" only classes with a bean defining annotation are discovered. All other classes are ignored. Any scope type is a bean defining annotation. If a scope type is declared on a bean class, then the bean class is said to have a bean defining annotation [spec]. The 1.1 spec is not completely clear here. Only classes with a @NormalScope scope or @Dependent pseudo scope are discovered, @javax.inject.Singleton and all other @Scope (pseudo) scopes are ignored.

Note that the definition of a "bean defining annotation" changed in CDI 1.2 and is now very well defined:

The set of bean defining annotations contains:

  • @ApplicationScoped, @SessionScoped, @ConversationScoped and @RequestScoped annotations,
  • all other normal scope types,
  • @Interceptor and @Decorator annotations,
  • all stereotype annotations (i.e. annotations annotated with @Stereotype), and the @Dependent scope annotation.



回答3:


I also agree with the answer form @rmuller. But I want to point out that there is still different behavior on application servers Payara and Wildfly. See the following example with a normal not scoped class but having a @EJB injection:

public class SomeClass  {
    @EJB
    MyService myService;

   ...
}

If you provide a beans.xml file with:

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

Payara 4.1 will treat the class SomeClass NOT as a CDI bean and will NOT inject the service EJB. This is clear to me that it behaves as stated in the specification.

But Wildfly 10 treats the class as an CDI bean and injects the service EJB which is not expected. To get this working the beans.xml file should look like this:

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

It's amazing that the two most common application servers are different here in behavior.



来源:https://stackoverflow.com/questions/18310388/meaning-of-bean-discovery-mode-annotated-in-cdi-1-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!