[As we continue with this series, we will refer to some content and examples from the CDI 2.x specification].
Suppose that you have more than one implementation of a bean to certify a service contract or you have more than one version of a bean you use for different purposes, such as an alternative bean (mock) for testing purposes.
Instead of writing different codes for choice selection of your bean, bean selection choice can be done at deployment time using alternatives.
Defining Alternative Beans.
To make the bean available for lookup, injection or for EL resolution, annotate your bean using @Alternative
anntations (FQN: javax.enterprise.inject.Alternative
).
@Alternative
public class MockOrder extends Order { ... }
By default @Alternative
beans are disabled. They are only activated for a specific bean archive by editing beans.xml
. You can also have several beans that implement the same interface, all annotated @Alternative
. In this case, you must specify in the beans.xml
file which of these alternative beans you want to use. The alternatives that you specify in the beans.xml
file apply only to classes in the same archive.
Using @Priority
to specify alternatives.
To enable an alternative bean globally for an application, especially when it has multiple modules use the @javax.annotation.Priority
annotation.
@Alternative
@Priority(100)
public class HighPriorityProcessor implements Processor { ... }
The alternative with higher priority value is selected if several alternative beans that implement the same interface are annotated with @Priority
. You do not need to specify the alternative in the beans.xml
file when you use the @Priority
annotation.
Example 03: CDI injection of @Alternative
bean (injection on interface, with 2 different implementations)
The tutorial source code can be found here and the running executable class file can be found here. The Service
interface has 2 different implementation: DefaultService
and AlternativeService
(annotated with @Alternative
).
The MainController
injects a Service
and without activating the AlternativeService
, the DefaultService
will be injected (as it's implicitly qualified as a @Default
qualifier).
If we want to ensure that AlternativeService
is injected inside MainController
, we activate it inside beans.xml
(source code can be found here).
<alternatives>
<class>za.co.sindi.tuts.jakartaee.cdi.example03.AlternativeService</class>
</alternatives>
Running the DefaultCDIMain
class, you will see the output Alternative Service work..
In the future tutorial we'll focus on @Stereotypes
and how to apply factory methods in CDI.
Top comments (1)
Particulary this post helped me a lot!
Thank you!