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?
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.
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With