Understanding Jakarta EE 8 CDI (Part 2): Qualifying Your Beans
Dive into bean qualification and discoverability using Jakarta EE 8's CDI qualifier types!
Join the DZone community and get the full member experience.Join For Free
[As we continue with this series, we will refer to some content and examples from the CDI 2.x specification].
In order for the CDI container to recognize your bean for injection, your bean needs to be qualified. This can be achieved by associating a bean with a qualifier type. A qualifier type represents some client-visible semantic associated with a type that is satisfied by some implementations of the type (and not by others). In other words, a qualifier type identifies a bean with a type that can be satisfied to one specific implementation of the same type (else it becomes an unsatisfied dependency).
Let’s look at how a bean can be qualified using a bean qualifier types.
Bean Qualifier Types
There’s 3 standard qualified types that are defined in the
@Any: Every bean has the built-in qualifier
@Any, even if it does not explicitly declare this qualifier, except for the special
@Default: If a bean does not explicitly declare a qualifier other than
@Named, the bean has the qualifier
@Newqualifier allows the application to obtain a new instance of a bean which is not bound to the declared scope, but has had dependency injection performed.
The following declarations are equivalent:
Both declarations result in a bean with two qualifiers:
The default qualifier is also assumed for any injection point that does not explicitly declare a qualifier, Thus, the following declarations, in which the use of the
@Inject annotation identifies the constructor parameter as an injection point, are equivalent:
In conclusion, the
@Any and the
@Default qualifier are always assumed during bean qualification, as well as at injection point when the qualifier hasn’t been explicitly declared.
@Named is defined by the package
javax.inject. This qualifier is used to specify the name of a bean. For example, this bean is named
The above declaration results in a bean with three qualifiers:
@Named is declared by the bean with no bean name provided, the default bean name is used, after converting the first character of the class name to lowercase. For example, using the example above, if
Order class was just annotated with
@Named, the default bean name will be
For more information, please refer to section 3.1.5 Default bean name for a managed bean.
@Named is not declared by the bean, nor by its stereotypes, a bean has no name.
Now that you have a basic insight on qualifying beans, let’s look at various examples of qualifying beans using bean qualifier types. Note that we’ve set the
all, the CDI container successfully recognized our classes as a qualified classes, ready for injection.
Example 1: CDI Injection of Implicit
@Default Bean Class (With no Interfaces)
The tutorial source code can be found here and the running executable class file can be found here and it follows the example as mentioned in the previous article. The
MainController classes are simple classes that don’t extend nor inherit any other class or interfaces respectively and has not been annotated with any bean qualifiers. This is due to the fact that all qualified bean are implicitly set as
Example 2: CDI Injection of Implicit
@Default Bean Class (Injection on Interface)
This is the extension of Example 1 but, in this case, the
DefaultService implements the
Service interface. The tutorial source code can be found here and the running executable class file can be found here. On the
MainController class, we simply inject on the property which links to the
Seeing that there are no annotations on
DefaultService, the CDI container has managed to successfully discovery one implementation of the
Service interface and, thus, create a contextual context around the
Service interface (which in turn will inject
DefaultService when needed).
DefaultService implicitly is qualified as a
Let’s pause here. In the next tutorial, we’ll look at how to tackle injections of classes/interfaces that can produce more than one dependency injections using
@Alternative as well as defining our own custom qualifier type.
Opinions expressed by DZone contributors are their own.