Meaning of bean discovery mode annotated in CDI 1.1

前端 未结 3 815
不知归路
不知归路 2020-11-30 08:52

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 specificat

相关标签:
3条回答
  • 2020-11-30 09:07

    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.
    0 讨论(0)
  • 2020-11-30 09:09

    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.

    0 讨论(0)
  • 2020-11-30 09:26

    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

    0 讨论(0)
提交回复
热议问题