@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD })
@Qualifier
public @interface PaymentQualifier {
	PaymentType type();
}CDI @Qualifier
Introdução
As vezes precisamos escrever várias implementações para uma interface de regras de negócios, para aumentar o desacoplamento vamos injetar apenas a interface e o CDI vai escolher a implementação correta, para ajudar o CDI com esta escolha nós criamos os qualificadores.
Exemplo
Neste exemplo, temos uma interface Payment e suas implementações:
* Cash
* CreditCard
Em nosso teste (Payment Test) nós injetamos somente a interface Payment, sem o recurso Qualificador, o CDI não saberia qual implementação injetar no teste.
Nós criamos um qualificador chamado PaymentQualifier um único qualificador com uma diferença, a anotação @Qualifier.
Este qualificador tem um método chamado type(), esse método ajudará o CDI a injetar corretamente a implementação. veja este enum:
public enum PaymentType {
	CASH,
	CREDITCARD
}agora veja uma implementação
@PaymentQualifier(type=PaymentType.CASH)
public class Cash implements Payment {
	@Override
	public String pay() {
		return "cash";
	}
}Cada implementação deve ser marcada com este qualificador.
Como injetar ? veja a simplicidade
public class PaymentTest {
    private static EJBContainer container;
    @Inject
    @PaymentQualifier(type=PaymentType.CREDITCARD) //qualificador informando o CDI sobre a implementação correta
    private Payment paymentCreditCard;
    @Inject
    @PaymentQualifier(type=PaymentType.CASH) //qualificador informando o CDI sobre a implementação correta
    private Payment paymentCash;
    @BeforeClass
    public static void start() {
        container = EJBContainer.createEJBContainer();
    }
    @Before
    public void setUp() throws Exception {
        container.getContext().bind("inject", this);
    }
    @Test
    public void mustReturnCreditCard() {
        assertEquals(paymentCreditCard.pay(), "creditCard");
    }
    @Test
    public void mustReturnCash() {
        assertEquals(paymentCash.pay(), "cash");
    }
    @AfterClass
    public static void stop() {
        container.close();
    }
}