Вводить компонент @EJB на основе условий

#jakarta-ee #ejb

#джакарта-ee #ejb

Вопрос:

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

Я установил некоторое значение в файле свойств. Если это правда, то я хочу

   public class MyClass{
    @EJB
    private MyBean bean;
  }
  

если оно равно false, то

 public class MyClass{
  @EJB
  private MyBean2 bean2;
 }
  

Выполнимо ли это?

Комментарии:

1. Выполнение поиска JNDI было бы жизнеспособной альтернативой, дающей то же постусловие, но перенос вашего кода между серверами приложений будет затруднен, поскольку путь JNDI по умолчанию к EJBS не стандартизирован.

Ответ №1:

Как сказал Гонсало, вам сначала нужно будет указать общий интерфейс компонента, если вы хотите объявить его как поле класса и использовать разные его реализации.

Более того, я думаю, вы могли бы сделать его более элегантным, используя метод CDI @Products; т.Е. несколько между этими строками:

 @Singleton
@Startup
public class Configuration {

    private boolean someCondition;

    @PostConstruct
    private void init() {
        someCondition = ... // get a value from DB, JMS, XML, etc.
    } 

    @EJB(lookup="java:comp/env/myParticularBean")
    MyBean myBean1;

    @EJB(beanName="anotherTypeOfBeanInjectedByName")
    MyBean myBean2;

    @Produces
    public MyBean produceMyBean() {
        if (someCondition)
            return myBean1;
        } else {
            return myBean2;
        }
    }
}
  

Затем в вашем коде вы можете просто использовать:

 @Inject
MyBean myBean;
  

и для вас будет введен соответствующий компонент, основанный на вашем условии.

Если вам не нужно поле на уровне класса, вы можете использовать старый способ и найти EJB в JNDI — таким образом, у вас есть контроль над тем, какой тип и какой компонент должен быть расположен и использоваться.

РЕДАКТИРОВАТЬ: я добавил @EJB аннотированные компоненты, чтобы показать, откуда могут быть получены экземпляры ‘myBean1’ и ‘myBean2’.

Этот пример показывает, что у вас может быть одно-единственное место, где вы определяете все свои зависимости от различных реализаций EJB и других компонентов. В примере это может быть реализовано как одноэлементный EJB с полями @EJB, полями @PersistenceContext и т. Д.

Вместо того, чтобы делать это представленным способом, вы можете изменить return myBean1 что-то вроде return context.lookup("JNDI_NAMESPACE_COORDINATES") where context is экземпляр InitialContext .

Надеюсь, это сделает его более понятным.

Комментарии:

1. спасибо за предложение. но я не совсем понимаю, как вернуть «myBean1» или «myBean2», когда возвращаемый тип «MyBean»? Не могли бы вы показать мне немного больше деталей?

2. myBean1 и myBean2 являются экземплярами классов, которые реализуют MyBean. Я обновлю вопрос, чтобы показать еще немного кода

3. Спасибо Педроковальски. итак, какой класс должен иметь метод «public MyBean produceMyBean ()»?

4. @neo все, что вам подходит 🙂 Это может быть одноэлементный EJB, если вы хотите использовать @EJB , как показано в примере. Это может быть обычный класс, если вы предпочитаете использовать поиск JNDI вручную.

5. Спасибо и взгляните на пример — надеюсь, на этот раз все будет понятнее.

Ответ №2:

Я не думаю, что вы можете изменить тип вводимого компонента. Я бы сказал, что это ограничение Java, поскольку это строго типизированный язык 🙂

Однако у вас может быть сценарий, в котором несколько компонентов реализуют один и тот же интерфейс, и вы хотите внедрить конкретную реализацию этого интерфейса следующим образом:

 @Local
public interface MyBean {
}

@Stateless
public class MyBeanImpl1 implements MyBean {
}

@Stateless
public class MyBeanImpl2 implements MyBean {
}
  

Тогда вы могли бы сделать:

 public MyClass {

@EJB(beanName="MyBeanImpl1")
MyBean myBean;

}
  

или

 public MyClass {

@EJB(beanName="MyBeanImpl2")
MyBean myBean;

}
  

В зависимости от реализации, которую вы хотите внедрить.

Комментарии:

1. Не самое лучшее решение, потому что, если вы решите изменить реализацию, вам придется перекомпилировать свой код.

2. На самом деле, @Neo запросил инъекции на основе условий. Не выбранные вручную инъекции.