Очень часто при инжекции зависимости мы указываем интерфейс или суперкласс. Чтобы указать контейнеру экземляр какого конкретного типа нужно создать используются квалификаторы (Qualifiers). Пример использования квалификаторов:
Создаем интерфейс, который будем далее инжектировать:
package main;
/**
*
* @author martyshov
*/
public interface Message {
public String getMessage();
}
Далее опишем два квалификатора
package main;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
*
* @author martyshov
*/
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ImplOne {
}
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
*
* @author martyshov
*/
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ImplTwo {
}
Далее создадим два бина и пометим их квалификаторами
package main;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
/**
*
* @author martyshov
*/
@Named
@RequestScoped
@ImplOne
public class MessageImpl1 implements Message {
/**
* Creates a new instance of MessageImpl1
*/
public MessageImpl1() {
}
@Override
public String getMessage() {
return "Это первая реализация интерфейса";
}
}
и второй
package main;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
/**
*
* @author martyshov
*/
@Named
@RequestScoped
@ImplTwo
public class MessageImpl2 implements Message {
/**
* Creates a new instance of MessageImpl2
*/
public MessageImpl2() {
}
@Override
public String getMessage() {
return "Это вторая реализация интерфейса";
}
}
Далее в бине, который будет связываться с фейслетом в точке инжекции укажем нужный квалификатор:
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
*
* @author martyshov
*/
@Named
@RequestScoped
public class MainBean {
/**
* Creates a new instance of MainBean
*/
public MainBean() {
}
@Inject
@ImplTwo
private Message msg;
public String getMessage(){
return msg.getMessage();
}
}
Если мы пометим бин аннотацией @Default, то он будет инжектирован если мы не укажем квалификатор в точке инжекции
package main;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
/**
*
* @author martyshov
*/
@Named
@RequestScoped
@Default
public class MessageImpl3 implements Message{
/**
* Creates a new instance of MessageImpl3
*/
public MessageImpl3() {
}
@Override
public String getMessage() {
return "Имплементация по умолчанию";
}
}
|