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

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
主站蜘蛛池模板: 乐平市| 乌审旗| 凌海市| 武川县| 黎平县| 社会| 社旗县| 尼玛县| 德惠市| 义马市| 谢通门县| 墨玉县| 永昌县| 盱眙县| 益阳市| 太康县| 蓝山县| 郯城县| 宜黄县| 全椒县| 青州市| 邮箱| 芮城县| 迁西县| 凯里市| 桑植县| 甘肃省| 莒南县| 屏东市| 壤塘县| 沭阳县| 定州市| 汕尾市| 双鸭山市| 延庆县| 雷州市| 靖江市| 新田县| 额敏县| 庄河市| 寿光市|