This is a case where the @Inject annotation is not required at the
injection point. The same is true for observer methods (which we’ll meet
in Chapter 11, Events) and disposer methods.

4.2. What gets injected

The CDI specification defines a procedure, called typesafe resolution,
that the container follows when identifying the bean to inject to an
injection point. This algorithm looks complex at first, but once you
understand it, it’s really quite intuitive. Typesafe resolution is
performed at system initialization time, which means that the container
will inform the developer immediately if a bean’s dependencies cannot be
satisfied.

The purpose of this algorithm is to allow multiple beans to implement
the same bean type and either:

allow the client to select which implementation it requires using a
qualifier or

allow the application deployer to select which implementation is
appropriate for a particular deployment, without changes to the client,
by enabling or disabling an alternative, or

allow the beans to be isolated into separate modules.

Obviously, if you have exactly one bean of a given type, and an
injection point with that same type, then bean A is going to go into
slot A. That’s the simplest possible scenario. When you first start your
application, you’ll likely have lots of those.

But then, things start to get complicated. Let’s explore how the
container determines which bean to inject in more advanced cases. We’ll
start by taking a closer look at qualifiers.

4.3. Qualifier annotations

If we have more than one bean that implements a particular bean type,
the injection point can specify exactly which bean should be injected
using a qualifier annotation. For example, there might be two
implementations of PaymentProcessor:

Qualifier annotations can also qualify method arguments of producer,
disposer and observer methods. Combining qualified arguments with
producer methods is a good way to have an implementation of a bean type
selected at runtime based on the state of the system:

If an injected field or a parameter of a bean constructor or initializer
method is not explicitly annotated with a qualifier, the default
qualifier,@Default, is assumed.

Now, you may be thinking, "What’s the different between using a
qualifier and just specifying the exact implementation class you want?"
It’s important to understand that a qualifier is like an extension of
the interface. It does not create a direct dependency to any particular
implementation. There may be multiple alternative implementations of
@Asynchronous PaymentProcessor!

4.4. The built-in qualifiers @Default and @Any

Whenever a bean or injection point does not explicitly declare a
qualifier, the container assumes the qualifier @Default. From time to
time, you’ll need to declare an injection point without specifying a
qualifier. There’s a qualifier for that too. All beans have the
qualifier`
@Any`. Therefore, by explicitly specifying @Any at an
injection point, you suppress the default qualifier, without otherwise
restricting the beans that are eligible for injection.

This is especially useful if you want to iterate over all beans with a
certain bean type. For example:

4.5. Qualifiers with members

Java annotations can have members. We can use annotation members to
further discriminate a qualifier. This prevents a potential explosion of
new annotations. For example, instead of creating several qualifiers
representing different payment methods, we could aggregate them into a
single annotation with a member:

4.7. Alternatives

Alternatives are beans whose implementation is specific to a particular
client module or deployment scenario. This alternative defines a mock
implementation of both @Synchronous PaymentProcessor and
@Asynchronous PaymentProcessor, all in one:

By default, @Alternative beans are disabled. We need to enable an
alternative in the beans.xml descriptor of a bean archive to make it
available for instantiation and injection. However, this activation only
applies to the beans in that archive. From CDI 1.1 onwards the
alternative can be enabled for the whole application using @Priority
annotation.

When an ambiguous dependency exists at an injection point, the container
attempts to resolve the ambiguity by looking for an enabled alternative
among the beans that could be injected. If there is exactly one enabled
alternative, that’s the bean that will be injected. If there are more
beans with priority, the one with the highest priority value is
selected.

4.8. Fixing unsatisfied and ambiguous dependencies

The typesafe resolution algorithm fails when, after considering the
qualifier annotations on all beans that implement the bean type of an
injection point and filtering out disabled beans (@Alternative beans
which are not explicitly enabled), the container is unable to identify
exactly one bean to inject. The container will abort deployment,
informing us of the unsatisfied or ambiguous dependency.

During the course of your development, you’re going to encounter this
situation. Let’s learn how to resolve it.

To fix an unsatisfied dependency, either:

create a bean which implements the bean type and has all the qualifier
types of the injection point,

make sure that the bean you already have is in the classpath of the
module with the injection point, or

explicitly enable an @Alternative bean that implements the bean type
and has the appropriate qualifier types, using beans.xml.

enable an @Alternative bean that implements the bean type and has
the appropriate qualifier types, using @Priority annotation.

To fix an ambiguous dependency, either:

introduce a qualifier to distinguish between the two implementations
of the bean type,

exclude one of the beans from discovery (either by means of
@Vetoed
or beans.xml),

disable one of the beans by annotating it @Alternative,

move one of the implementations to a module that is not in the
classpath of the module with the injection point, or

disable one of two @Alternative beans that are trying to occupy the
same space, using beans.xml,

change priority value of one of two @Alternative beans with the
@Priority if they have the same highest priority value.

Now there’s one more issue you need to be aware of when using the
dependency injection service.

4.9. Client proxies

Clients of an injected bean do not usually hold a direct reference to a
bean instance, unless the bean is a dependent object (scope
@Dependent).

Imagine that a bean bound to the application scope held a direct
reference to a bean bound to the request scope. The application-scoped
bean is shared between many different requests. However, each request
should see a different instance of the request scoped bean—the current
one!

Now imagine that a bean bound to the session scope holds a direct
reference to a bean bound to the application scope. From time to time,
the session context is serialized to disk in order to use memory more
efficiently. However, the application scoped bean instance should not be
serialized along with the session scoped bean! It can get that reference
any time. No need to hoard it!

Therefore, unless a bean has the default scope @Dependent, the
container must indirect all injected references to the bean through a
proxy object. This client proxy is responsible for ensuring that the
bean instance that receives a method invocation is the instance that is
associated with the current context. The client proxy also allows beans
bound to contexts such as the session context to be serialized to disk
without recursively serializing other injected beans.

Unfortunately, due to limitations of the Java language, some Java types
cannot be proxied by the container. If an injection point declared with
one of these types resolves to a bean with any scope other than
@Dependent, the container will abort deployment, informing us of the
problem.

The following Java types cannot be proxied by the container:

classes which don’t have a non-private constructor with no parameters,
and

classes which are declared final or have a final method,

arrays and primitive types.

It’s usually very easy to fix an unproxyable dependency problem. If an
injection point of type X results in an unproxyable dependency,
simply:

add a constructor with no parameters to X,

change the type of the injection point to`Instance<X>`,

introduce an interface Y, implemented by the injected bean, and
change the type of the injection point to Y, or

if all else fails, change the scope of the injected bean to
@Dependent.

Note

Weld also supports a non-standard workaround for this limitation, using
non-portable JVM APIs:

Sun, IcedTea, Mac: Unsafe.allocateInstance() (The most efficient)

IBM, JRockit: ReflectionFactory.newConstructorForSerialization()

To enable this workaround, simply put an empty marker file
META-INF/org.jboss.weld.enableUnsafeProxies somewhere on the
application’s classpath.

4.10. Obtaining a contextual instance by programmatic lookup

In certain situations, injection is not the most convenient way to
obtain a contextual reference. For example, it may not be used when:

the bean type or qualifiers vary dynamically at runtime, or

depending upon the deployment, there may be no bean which satisfies
the type and qualifiers, or

we would like to iterate over all beans of a certain type.

In these situations, the application may obtain an instance of the
interface Instance, parameterized for the bean type, by injection:

@InjectInstance<PaymentProcessor> paymentProcessorSource;

The get() method of Instance produces a contextual instance of the
bean.

PaymentProcessor p = paymentProcessorSource.get();

Qualifiers can be specified in one of two ways:

by annotating the Instance injection point, or

by passing qualifiers to the select() of Event.

Specifying the qualifiers at the injection point is much, much easier:

Next, we need to obtain an instance of our qualifier type. Since
annotations are interfaces, we can’t just write new Asynchronous().
It’s also quite tedious to create a concrete implementation of an
annotation type from scratch. Instead, CDI lets us obtain a qualifier
instance by subclassing the helper class AnnotationLiteral.

4.11. The InjectionPoint object

There are certain kinds of dependent objects (beans with scope
@Dependent) that need to know something about the object or injection
point into which they are injected in order to be able to do what they
do. For example:

The log category for a Logger depends upon the class of the object
that owns it.

Injection of a HTTP parameter or header value depends upon what
parameter or header name was specified at the injection point.

Injection of the result of an EL expression evaluation depends upon
the expression that was specified at the injection point.

A bean with scope @Dependent may inject an instance of
InjectionPoint and access metadata relating to the injection point to
which it belongs.

Let’s look at an example. The following code is verbose, and vulnerable
to refactoring problems: