我可以使用lamba experssion通过带有CDI的策略模式动态获取ejb吗?

时间:2018-09-26 10:02:00

标签: java lambda cdi ejb-3.1 strategy-pattern

我知道我可以将与接口匹配的所有bean作为实例注入,然后以编程方式在它们之间进行选择:

@Inject @Any Instance<PaymentProcessor> paymentProcessorSource;

这意味着我必须将选择逻辑放入客户端。

我是否可以使用带Lambda表达式的词法作用域来缓存ejb的值?在这种情况下,容器将能够正确管理ejb的生命周期,还是应避免这种做法?

例如,将PaymentProcessorImpl1 e PaymentProcessorImpl2作为PaymentProcessor的两种策略,如下所示:

public class PaymentProcessorProducer {

@Inject
private PaymentProcessorImpl1 paymentProcessorImpl1;

@Inject
private PaymentProcessorImpl2 paymentProcessorImpl2;

@Produces
private Function<String, PaymentProcessor> produce() {

    return (strategyValue) -> {

        if ("strategy1".equals(strategyValue)) {

            return paymentProcessorImpl1;

        } else if ("strategy2".equals(strategyValue)) {

            return paymentProcessorImpl2;

        } else {
            throw new IllegalStateException("Tipo non gestito: " 
                    + strategyValue);
        }

    };

}

}

然后进入客户端,如下所示:

@Inject
Function<String, PaymentProcessor> paymentProcessor;

...

paymentProcessor.apply("strategy1")

1 个答案:

答案 0 :(得分:1)

  

我是否可以使用带Lambda表达式的词法作用域来缓存ejb的值?

理论上,您可以这样做。是否可行,我们可以轻松尝试。

  

在这种情况下,容器是否能够正确管理ejb的生命周期?还是可以避免这种做法?

这里的EJB到底是什么? PaymentProcessor的实现?注意,EJB bean与CDI bean不同。由于在CDI容器中不能控制EJB Bean的生命周期,因此它“仅提供包装器供您使用,就像它们是CDI Bean一样。”

话虽如此,生命周期仍然相同-在您的情况下,生产者正在创建@Dependent bean,这意味着每次您注入Function<String, PaymentProcessor>时,都会调用生产者。

带来某些问题的是,您在任何给定时间都基于两个或多个上下文处于活动状态创建了一个假设。在您决定实际使用apply()函数的那一刻,实现的存在范围可能有效,也可能无效。例如,如果它们都是ApplicationScoped,那么应该没问题。但是,如果它们是SessionScoped,而您碰巧在应用函数之前超时/使会话无效,那么您将进入一个非常奇怪的状态。

这可能就是为什么我宁愿避免使用这种方法并使用限定符的原因。或者,您可以引入一个既有策略又有方法的新bean,该方法的参数决定使用哪种策略。