INTRODUÇÃO
Vamos começar falando um pouco sobre os qualificadores da CDI, como muitos devem saber a CDI a uma especificação JAVA que deu muito poder e extensividade a Linguagem, não vou entrar no mérito de falar sobre a especificação, apenas sobre a funcionalidade de Qualificadores.
QUALIFICADORES OU QUALIFIER
Imagine que temos uma interface com várias implementações, uma das utilidades dos qualifier é informarmos qual implementação vamos usar, se liga no exemplo.
public interface PaymentMethod {
public void pay();
}
ai temos 2 implementações para a interface PaymentMethod
public class CreditCard implements PaymentMethod {
@Override
public void pay() {
System.out.println("payment by cred card");
}
}
public class Cash implements PaymentMethod {
@Override
public void pay() {
System.out.println("payment by CASH");
}
}
Se em nossa classe cliente apenas injetarmos a interface PaymentMethod a CDI lançará uma exceção de ambiguidade, informando que não sabe qual implementação irá injetar, tranquilo até ai ?
public class Checkout {
@Inject
private PaymentMethod payment;
public void checkout() {
payment.pay();
}
}
Da uma olha no error que vai aparecer no seu console.
WELD-001475: The following beans match by type, but none have matching qualifiers:
- Managed Bean [class br.com.cassunde.cdi.qualifier.Cash] with qualifiers [@Any @Payment],
- Managed Bean [class br.com.cassunde.cdi.qualifier.CreditCard] with qualifiers [@Any @Payment]
Para resolvermos isso teremos que criar um qualifier CDI, a sua criação e bem simples, basta criar uma anotação java padrão com uma pequena diferença, essa nossa anotação terá um @Qualifier, como o próprio nome já diz, será o responsável por indicar que essa nossa anotação e um qualifier. ficara mais ou menos assim.
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
@Qualifier
public @interface PaymentCreditCard {}
vamos fazer um exemplo ruim e depois vamos ver uma forma melhor de resolver esse problema usando qualifier, em nosso exemplo a interface PaymentMethod tem 2 implementações a CreditCard e a Cash, em nossa abordagem ruim faremos uma outra anotação para qualificarmos a segunda implementação então vamos lá: Qualifier para Implementação Cash:
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
@Qualifier
public @interface PaymentCash {}
para usarmos esses qualifier ficara mais ou menos assim: - Implementação CreditCard
@PaymentCreditCard
public class CreditCard implements PaymentMethod {
@Override
public void pay() {
System.out.println("payment by creditcard");
}
}
Classe cliente
public class Checkout {
@Inject
@PaymentCreditCard
private PaymentMethod payment;
public void checkout() {
System.out.println("Starting checkout");
payment.pay();
}
}
Dessa forma não fica muito legal, caso apareça uma nova implementação teremos que criar uma nova anotação e por ai vai… vamos agora melhorar essa abordagem, vamos inserir uma enum em nosso qualifier.
Vou criar essa enum e um terceiro qualifier chamado Payment
public enum PaymentType {
CREDIT,
CASH,
DEBIT
}
Nosso terceiro qualifier ficaria assim:
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
@Qualifier
public @interface Payment {
PaymentType type();
}
agora podemos substituir os primeiros qualifier que criamos por esse último, ficando mais ou menos assim:
Implementação CreditCard
@Payment(type=PaymentType.CREDIT)
public class CreditCard implements PaymentMethod {
@Override
public void pay() {
System.out.println("payment by cred card");
}
}
Método Cliente
public class Checkout {
@Inject
@Payment(type=PaymentType.CREDIT)
private PaymentMethod payment;
public void checkout() {
System.out.println("Starting checkout");
payment.pay();
}
}
Implementação Cash
@Payment(type=PaymentType.CASH)
public class Cash implements PaymentMethod {
@Override
public void pay() {
System.out.println("payment by cred card");
}
}
Método Cliente
public class Checkout {
@Inject
@Payment(type=PaymentType.CASH)
private PaymentMethod payment;
public void checkout() {
System.out.println("Starting checkout");
payment.pay();
}
}
Observem que agora estamos usando apenas uma única anotação e estamos “tipando” nosso qualifier, dessa forma temos mais liberdade para evoluir o código.
Por enquanto e só isso.
Curtiu ? Me segue nas redes 😉