DEV Community

Mattheus Cassundé
Mattheus Cassundé

Posted on

Qualificadores no CDI

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();
}
Enter fullscreen mode Exit fullscreen mode

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");
    }
}
Enter fullscreen mode Exit fullscreen mode
public class Cash implements PaymentMethod {

    @Override
    public void pay() {
        System.out.println("payment by CASH");
    }
}
Enter fullscreen mode Exit fullscreen mode

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();
    }

}
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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");
    }
}
Enter fullscreen mode Exit fullscreen mode

Classe cliente

public class Checkout {

    @Inject
    @PaymentCreditCard
    private PaymentMethod payment;

    public void checkout() {
        System.out.println("Starting checkout");
        payment.pay();
    }
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

Nosso terceiro qualifier ficaria assim:

@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
@Qualifier
public @interface Payment {
    PaymentType type();
}
Enter fullscreen mode Exit fullscreen mode

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");
    }
}
Enter fullscreen mode Exit fullscreen mode

Método Cliente

public class Checkout { 

    @Inject
    @Payment(type=PaymentType.CREDIT)
    private PaymentMethod payment; 

    public void checkout() {
        System.out.println("Starting checkout");
        payment.pay();
    }
}
Enter fullscreen mode Exit fullscreen mode

Implementação Cash

@Payment(type=PaymentType.CASH)
public class Cash implements PaymentMethod {

    @Override
    public void pay() {
        System.out.println("payment by cred card");
    }
}
Enter fullscreen mode Exit fullscreen mode

Método Cliente

public class Checkout { 

    @Inject
    @Payment(type=PaymentType.CASH)
    private PaymentMethod payment; 

    public void checkout() {
        System.out.println("Starting checkout");
        payment.pay();
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up