As I described in my previous [post][1], we can define and inject cdi beans by @Named
annotation. Well according to the CDI specification (JSR-299) injecting beans by their names is legacy and tend to cause issues (if a bean is tried to be injected by an undefined/wrong name then we will get errors which are hard to find). Thus, we are going to create different annotations (qualifiers) to inject different type of beans from same interface. Moreover, we will use Weld CDI implementation.
Create a Qualifier
Creating your own qualifier is easy. We have to create a standard annotation and mark it with @Qualifier
.
import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface <annotation_name> {
}
So, according to the qualifier template we will need three annotations; Bmw, Honda, and Ford.
Bmw.java
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface Bmw {
}
Honda.java
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface Honda {
}
Ford.java
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({FIELD, METHOD, TYPE, PARAMETER})
public @interface Ford {
}
Notes
-
Retention</b> determines at what point an annotation is discarded. More explanation can be seen from here.
</li>
- Target</b> defines the type of our annotation. Explanation with clear examples can be seen from here. </li> </ul> </div> I will again use the same code examples which I used in my previous posts. There is one interface called AutoService and three implementations of it. AutoService.java
BMWAutoService.javapublic interface AutoService { String getService(); }
FordAutoService.java@Bmw public class BMWAutoService implements AutoService{ @Override public String getService() { return "You chose BMW auto service"; } }
HondaAutoService.java@Ford public class FordAutoService implements AutoService{ @Override public String getService() { return "You chose Ford auto service"; } }
Now we are completely ready to inject our cdi beans by their qualifiers! So, lets see three different injection examples – Field, Constructor and Setter method injection -.@Honda public class HondaAutoService implements AutoService{ @Override public String getService() { return "You chose Honda auto service"; } }
1. Injection Through Fields
public class Example { @Inject @Bmw private AutoService bmwAutoService; @Inject @Honda private AutoService hondaAutoService; @Inject @Ford private AutoService fordAutoService; ... }
2.Injection Through Setter Methods
public class Example { private AutoService bmwAutoService; private AutoService hondaAutoService; private AutoService fordAutoService; @Inject public void setBmwAutoService(@Bmw AutoService bmwAutoService) { this.bmwAutoService = bmwAutoService; } @Inject public void setHondaAutoService(@Honda AutoService hondaAutoService) { this.hondaAutoService = hondaAutoService; } @Inject public void setFordAutoService(@Ford AutoService fordAutoService) { this.fordAutoService = fordAutoService; } ... }
3.Injection Through Constructor
There is also a second way to use qualifiers to prevent from annotation overflow. In normal life we have tens of auto models. So, instead of creating lots of qualifiers, we can only create one qualifier and enum to define the type of annotation we want to use -enum is optional we can specify types by integer, string etc-. With this way we will be able to handle lots of annotations easily. Let us see; AutoType.javapublic class AutoServiceCallerImp private AutoService bmwAutoService; private AutoService hondaAutoService; private AutoService fordAutoService; @Inject public AutoServiceCallerImp(@Bmw AutoService bmwAutoService, @Honda AutoService hondaAutoService, @Ford AutoService fordAutoService) { this.bmwAutoService = bmwAutoService; this.fordAutoService = fordAutoService; this.hondaAutoService = hondaAutoService; } ... }
Auto.javapublic enum AutoType { Bmw, Ford, Honda }
@Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({METHOD, TYPE, PARAMETER, FIELD}) public @interface Auto { AutoType type() default AutoType.Bmw; }
default
property is optional here. It means if we dont specify a type then the default value will be used. Now let's an example by field injection.
So, as we can see we define the type of our cdi beans just by giving type value, and we have only usedpublic class AutoServiceCallerImp implements AutoServiceCaller{ @Inject @Auto(type = AutoType.Bmw) private AutoService bmwAutoService; @Inject @Auto(type = AutoType.Honda) private AutoService hondaAutoService; @Inject @Auto(type = AutoType.Ford) private AutoService fordAutoService; ... }
@Auto
annotation. [1]: http://buraktas.com/java-cdi-dependency-injection-example/ - Target</b> defines the type of our annotation. Explanation with clear examples can be seen from here. </li> </ul> </div> I will again use the same code examples which I used in my previous posts. There is one interface called AutoService and three implementations of it. AutoService.java
Comments powered by Disqus.