官术网_书友最值得收藏!

Using producers

As shown earlier, a bean can have different alternatives, by introducing one interface and providing different implementations, each with a different qualifier. When injecting a reference to this interface in another bean, you can annotate your injection point with the qualifier for the implementation you desire. One interesting question is, can we specify which implementation to inject according to some runtime parameters, such as a user-specified choice?

For example, suppose a user is engaged in a payment workflow process. The first step is that the user will choose which payment method they prefer and where the next step they will actually perform the payment transaction. Suppose you have a PaymentStrategy interface with different bean implementations for a credit card, PayPal, and check payment strategies. Can we specify which bean implementation to reference according to the user choice? The answer is yes! This is called runtime polymorphism, and it can be achieved using producers.

A producer is a method that acts as a source of CDI beans. Consider the following example for a bean with different implementations:

public interface PaymentStrategy { ... } 
 
public class CreditCardPaymentStrategy implements PaymentStrategy{ ... } 
 
public class CheckPaymentStrategy implements PaymentStrategy{ ... } 
 
public class PayPalPaymentStrategy implements PaymentStrategy{ ... } 
 

Let's define a Preferences bean. The preferences bean will act as a representation for the user-chosen preferences, and will include a producer method as follows:

@SessionScoped 
public class Preferences implements Serializable { 
 
    public static final int CREDIT_CARD = 0; 
    public static final int CHECK = 1; 
    public static final int PAYPAL = 2; 
    private int paymentStrategy = ...; 
 
    @Produces 
    @Preferred 
    public PaymentStrategy getPaymentStrategy() { 
 
        switch (paymentStrategy) { 
 
            case CREDIT_CARD: 
                return new CreditCardPaymentStrategy(); 
 
            case CHECK: 
                return new CheckPaymentStrategy(); 
 
            case PAYPAL: 
                return new PayPalPaymentStrategy(); 
 
            default: 
                return null; 
 
        } 
    } 
} 

The getPaymentStrategy method is annotated with a @Produces annotation and this is called a producer method. It returns an instance for a PaymentStrategy implementation. The @Preferred annotation is a qualifier that will be used when injecting a reference to our bean, as follows:

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

Now, assume you have injected a reference to a PaymentStrategy as follows:

@Inject @Preferred PaymentStrategy paymentStrategy; 

The method will run and detect which choice was made by the user for their preferred payment strategy, and, will return the appropriate implementation. The producer method technique is really useful when you need to choose one implementation in runtime according to a given parameter. However, there are other cases when using the producer method is useful, such as:

  • You need to inject objects that are not real CDI beans
  • You need to satisfy some initial values for your bean and/or performing some initial operations
主站蜘蛛池模板: 黄大仙区| 定日县| 郧西县| 万年县| 赤壁市| 西昌市| 双柏县| 恭城| 丰宁| 霍州市| 贡觉县| 元阳县| 富源县| 桃园县| 苗栗县| 武安市| 收藏| 南京市| 铜川市| 驻马店市| 夏河县| 会同县| 额济纳旗| 桑植县| 嘉义市| 满城县| 静乐县| 临朐县| 鸡西市| 荣成市| 勐海县| 会同县| 永和县| 长沙县| 旅游| 和田市| 太湖县| 青冈县| 荔波县| 泰宁县| 富民县|