Внедрить бин @EJB в зависимости от условий - PullRequest
11 голосов
/ 27 октября 2011

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

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

  public class MyClass{
    @EJB
    private MyBean bean;
  }

если это ложно, то

public class MyClass{
  @EJB
  private MyBean2 bean2;
 }

Это выполнимо?

Ответы [ 2 ]

20 голосов
/ 28 октября 2011

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

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

@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 - таким образом, вы можете контролировать, какой тип и какой компонент должен быть расположен и использован.

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

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

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

Надеюсь, это прояснит ситуацию.

2 голосов
/ 28 октября 2011

Я не думаю, что вы можете изменить тип вводимого компонента.Я бы сказал, что это ограничение 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;

}

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

...