How to use CDI qualifiers with multiple class implementations?

I am new to Java EE / JSF and am now reading about CDI qualifiers - the ability to change the implementation of a class. This is great, but I have one question. As far as I understand, I can change the implementation of the class using the qualifier, but I need to change it wherever I use this implementation. What is the best solution to do this in one place? With my little knowledge of Java EE, I figured this out.

Lets imagine that we are creating a simple calculator application. We need to create several classes:

  • Calculator (basic calculator implementation)
  • ScientificCalculator (scientific implementation of the calculator)
  • MiniCalculator (with minimal potentiality)
  • MockCalculator (for unit tests)
  • Qualifier @Calculator(will indicate the actual implementation of the calculator, should I create a qualifier for each implementation?)

That is the question. I have four implementations of the calculator, and I want to use one of them in several places, but only one at a time (at the initial stage of the project I will use MiniCalculator, then Calculator, etc.). How can I change the implementation without the change code in all places where the object is entered? Should I create a factory that will be responsible for the injection and will work like method injector? Is my decision right and meaningful?

Factory

@ApplicationScoped
public class CalculatorFctory implements Serializable {
    private Calculator calc;

    @Produces @Calculator Calculator getCalculator() {
        return new Calculator();
    }
}

Class that uses a calculator

public class CalculateUserAge {
    @Calculator
    @Inject
    private Calculator calc;
}

This is the right decision? Please correct me if I am wrong or if there is a better solution. Thank!.

+5
source share
2

factory, factory beans, CDI, @Calculator.

    @ApplicationScoped
     public class CalculatorFactory implements Serializable {
     enum CalculatorType{MiniCaculator,ScientificCaculator,MockCalculator};   
     Calculator getCalculator(CalculatorType calctype) {
                switch(calctype)
                  case MiniCaculator : return new MiniCalculator();
                  case ScientificCalculator : new ScientificCalculator();
                  case MockCalculator : new MockCalculator();
                  default:return null;
            }
        }
public class CalculatorScientificImpl {       
    private Calculator calc    =  
          CalculatorFactory.getCaclulator(CaclutorType.ScientificCalculator);
    doStuff(){}
}

public class CalculatorTest {       
    private Calculator calc    =
               CalculatorFactory.getCaclulator(CaclutorType.MockCalculator);
    doStuff(){}
}

, , Caclulator beans CDI , @PostConstruct .., .

1:

: @Named ( "miniCaclulator" )

: complier , say miniCaclulator xyzCaclulator.

@Named("miniCaclulator")
class MiniCalculator implements Calculator{ ... }

@ApplicationScoped
public class CalculatorFactory implements Serializable {
    private calc;

    @Inject 
    void setCalculator(@Named("miniCaclulator") Caclulator calc) {
        this.calc = calc;
    }
}

2: ( , - )

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
public @interface MiniCalculator{
}

@ApplicationScoped
public class CalculatorFctory implements Serializable {
    private calc;

    @Inject 
    void setCalculator(@MiniCalculator calc) {
        this.calc = calc;
    }
}

3: factory . CDI, Injection , @Inject.

@ApplicationScoped
public class CalculatorFactory implements Serializable {
    private Calculator calc;    
    @Produces Calculator getCalculator() {
        return new Calculator();
    }
}    
public class CalculateUserAge {
    @Inject
    private Calculator calc;
}

, , CaculatorTest,

class ScientificCalculatorTest{        
    Caclulator scientificCalculator;        
    @Inject 
    private void setScientificCalculator(@ScientificCalculator calc) {
                this.scientificCalculator = calc;
            }        
    @Test
    public void testScientificAddition(int a,int b){
      scientificCalculator.add(a,b);
      ....
    } 
    }

, - ,

   class CalculatorTest{        
        Caclulator calc;        
        @PostConstruct 
                init() {
                    this.calc = createMockCaclulator();
                }
        @Test
        public void testAddition(int a,int b){
          calc.add(a,b);
          .....
        }
        }
+9

.

  • ? @Alternatives.
  • ? , . .
  • , ? , , . , / @PostConstruct. . . 2. .
  • ? , , 1.. @Calculator Calculator . , . 2.

    @ApplicationScoped
    public class CalculatorFctory implements Serializable {
        private Calculator calc;
    
        @Produces @Calculator Calculator getCalculator() {
            return new Calculator();
        }
    }
    

Update:

CDI . , , , , , . , .

:

public class ImplOne implements MyInterface {
    ...
}

public class ImplTwo implements MyInterface {
    ...
}

, - :

@Inject ImplOne bean;

@Inject ImplTwo bean;

, @Calculator Calculator . , , . , @QualOne @QualTwo:

@Inject @QualOne ImplOne bean;

@Inject @QualTwo ImplTwo bean;

, .

, , :

@Inject @QualOne MyInterface bean; // to inject TypeOne

@Inject @QualTwo MyInterface bean; // to inject TypeTwo

OP @Produces, , CBC CDI.

@Avinash Singh - CDI @Produces, , , CDI, . . , . `@... Scoped beans, , ..

, :

public class SomeProducer {

    @Inject ImplOne implOne;
    @Inject ImplTwo implTwo;
    @Inject ImplThree implThree;

    @Produces
    public MyInterface get() {
        if (conditionOne()) {
            return implOne;
        } else if (conditionTwo()) {
            return implTwo;
        } else {
            return implThree;
        }
    }
}

public class SomeProducer {

    @Produces
    public MyInterface get() {
        if (conditionOne()) {
            return new ImplOne();
        } else if (conditionTwo()) {
            return new ImplTwo();
        } else {
            return new ImplThree;
        }
    }
}

CDI (.. @PostConstruct @Inject ) , , .

- ? , , .

@Default
public class ImplOne implements MyInterface {
    ...
}

@Alternative
public class ImplTwo implements MyInterface {
    ...
}

@Alternative
public class ImplThree implements MyInterface {
    ...
}

@Inject MyInterface instance, ImplOne ,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    <alternatives>
        <class>ImplTwo</class>
    </alternatives>
</beans>

ImplTwo .

Java EE , CDI, EJB -.

- CDI bean? :

@WebServiceRef(lookup="java:app/service/PaymentService")
PaymentService paymentService;

, , CDI.

, @WebServiceRef(lookup="java:app/service/PaymentService") , ? , ? -:

@Produces @WebServiceRef(lookup="java:app/service/PaymentService")
PaymentService paymentService;

CDI bean, , @Inject CDI :

@Inject PaymentService paymentService;

, PaymentService CDI. -. , - CDI, - CDI.

+9

All Articles