Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of bean discovery mode annotated in CDI 1.1

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?

like image 481
Oliver Avatar asked Aug 19 '13 09:08

Oliver


People also ask

Which annotation is used to instantiate CDI beans?

As you may have noticed, the bean is nothing more than a plain old Java object, annotated with the @Dependent annotation. This annotation, called the dependent scope, declares that POJO is a CDI component. The dependent scope tells the CDI context to create a new instance whenever you request an injection to this bean.

What is CDI bean?

A CDI bean is a POJO, plain old java object, that has been automatically instantiated by the CDI container, and is injected into all, and any qualifying injection points in the application. The CDI container initiates the bean discovery process during deployment.

What is a bean archive?

A bean archive is any module that contains beans that the CDI runtime can manage and inject. There are two kinds of bean archives: explicit bean archives and implicit bean archives.

What is JSF CDI?

Getting Started with CDI and JSF 2.0 Contexts and Dependency Injection (CDI), specified by JSR-299, is an integral part of Java EE 6 and provides an architecture that allows Java EE components such as servlets, enterprise beans, and JavaBeans to exist within the lifecycle of an application with well-defined scopes.


2 Answers

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.
like image 196
rmuller Avatar answered Sep 19 '22 15:09

rmuller


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

like image 32
Ian Evans Avatar answered Sep 17 '22 15:09

Ian Evans