Understanding Jakarta EE 8 - C.D.I. (Part 2) - Qualifying your beans.
Tags: java, jakartaee, programming, tutorial
Published: 2020-12-13 01:41:01

[As we continue with this series, we will refer to some content and examples from the [CDI 2.x specification](https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html)].

In order for the CDI container to recognise 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 `javax.enterprise.inject` package:

 1. `@Any`: Every bean has the built-in qualifier `@Any`, even if it does not explicitly declare this qualifier, except for the special `@New`.
 2. `@Default`: If a bean does not explicitly declare a qualifier other than `@Named`, the bean has the qualifier `@Default`. 
 3. `@New`: The `@New` qualifier 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:
```java
@Default
public class Order { ... }
```
```java
public class Order { ... }
```

Both declarations result in a bean with two qualifiers:  `@Any`  and  `@Default`.

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:

```java
public class Order {
    @Inject
    public Order(@Default OrderProcessor processor) { ... }
}
```
```java
public class Order {
    @Inject
    public Order(OrderProcessor processor) { ... }
}
```
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.

## The `@Named` Qualifier
The `@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  `currentOrder`:

```java
@Named("currentOrder")
public class Order { ... }
```

The above declaration results in a bean with three qualifiers: `@Any`, `@Default` and `@Named("currentOrder")`.

If `@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 `order`.

For more information, please refer to [section 3.1.5 Default bean name for a managed bean](https://jakarta.ee/specifications/cdi/2.0/cdi-spec-2.0.html#managed_bean_name).

If `@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 [`bean-discovery-mode` as `all`](https://github.com/TheEliteGentleman/jakartaee8-tuts-cdi/blob/master/src/main/resources/META-INF/beans.xml), the CDI container successfully recognised 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](https://github.com/TheEliteGentleman/jakartaee8-tuts-cdi/tree/master/src/main/java/za/co/sindi/tuts/jakartaee/cdi/example01) and the running executable class file can be found [here](https://github.com/TheEliteGentleman/jakartaee8-tuts-cdi/tree/master/src/test/java/za/co/sindi/tuts/jakartaee/cdi/example01) and it follows the example as mentioned in the previous article. The `DefautService` and `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 `@Any` and `@Default`. 

## 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](https://github.com/TheEliteGentleman/jakartaee8-tuts-cdi/tree/master/src/main/java/za/co/sindi/tuts/jakartaee/cdi/example02) and the running executable class file can be found [here](https://github.com/TheEliteGentleman/jakartaee8-tuts-cdi/tree/master/src/test/java/za/co/sindi/tuts/jakartaee/cdi/example02).  On `MainController` class we simply inject on the property which links to the `Service` interface.
Seeing that there are no annotations on `DefaultService`, the CDI container has managed to successfully discovery one implementation of the `Service` interface and thus, creating a contextual context around the `Service` interface (which in turn will inject `DefaultService` when needed).
The `DefaultService` implicitly is qualified as a `@Any` and `@Default`.

Let's pause on here. In the next tutorial we'll look on how to tackle injections of classes / interfaces that can produce more than 1 dependency injections using `@Alternative` as well as defining our own custom qualifier type.