Могу ли я использовать lamba Experssion для динамического получения ejb с помощью паттерна стратегии с CDI? - PullRequest
0 голосов
/ 26 сентября 2018

Я знаю, что могу в качестве примера внедрить все bean-компоненты, которые соответствуют интерфейсу, и затем программно выбирать между ними:

@Inject @Any Instance<PaymentProcessor> paymentProcessorSource;

Это означает, что я должен поместить логику выбора в клиент.

Могу ли я, в качестве альтернативы, кэшировать значение 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 голосов
/ 26 сентября 2018

Могу ли я, в качестве альтернативы, кэшировать значение ejb, используя лексическую область видимости с лямбда-выражением?

Теоретически, вы можете сделать это.Работать ли это легко, мы можем попробовать сами.

Сможет ли контейнер правильно управлять жизненным циклом ejb в этом случае, или этой практики следует избегать?

Что именно EJB здесь?Реализация PaymentProcessor?Обратите внимание, что EJB-компоненты отличаются от CDI-компонентов.Так как в контейнере CDI не контролируется жизненный цикл EJB-компонентов, он «предоставляет вам только оболочку для их использования, как если бы они были CDI-бинами».

При этом жизненный цикл остается тем же - в вашемесли производитель создает @Dependent bean, то есть каждый раз, когда вы вводите Function<String, PaymentProcessor>, будет вызван производитель.

Что создает определенную проблему, так это то, что вы создаете предположение о том, что два или более контекста активны в любой данный момент.время.В тот момент, когда вы решите на самом деле apply() функцию, область действия вашей реализации может быть или не быть активной.Например, если они оба ApplicationScoped, вы должны быть в порядке.Однако, если они равны SessionScoped, и вам случается прервать / аннулировать сеанс перед применением функции, то вы попадаете в очень странное состояние.

Возможно, поэтому я бы предпочел избегать такого подхода и использовать квалификаторы.Или вы можете представить новый бин, в котором есть обе стратегии и есть метод с аргументом, который решает, какую стратегию использовать.

...