2017-01-07 5 views
0

Я пытаюсь выяснить, как объект-экземпляр работает в Java EE. Я заметил, что я получаю исключение NullPointerException, если я пытаюсь получить доступ к члену, который должен быть введен через @EJB, если класс, определяющий элемент, был явным образом определен мной, а не контейнером. Мое заключение состоит в том, что даже если бит будет отмечен как управляемый, это не значит, что он не позволяет контейнеру его создавать. Можем ли мы заставить контейнер управлять такими объектами?Injecting @EJB в явно созданный объект -> NullPointerException

Предположим, что у нас есть следующая настройка: можно ли было бы создавать (явно) ClassB в ClassC и иметь ClassB вызывать метод из ClassA, не бросая исключение NullPointerException?

@Stateless 
public class ClassA { 
    public void bar() { 
     // Does something fun 
    } 
} 

@Stateless 
public class ClassB { 
    @EJB 
    private ClassA A; 

    public void foo() { 
     A.bar(); // throws NullPointerException if ClassB 
       // is explicitly instantiated works fine 
       // if injected with @EJB 
    } 
} 

public class ClassC { 
    //@EJB // Only way to go? Can we choose an implementation of ClassB? 
    private ClassB B; 

    public ClassC() { 
     this.B = new ClassB(); // Bad idea? Possible?? 
     this.B.foo(); 
    } 
} 

Причина Я ищу в него, потому что я в моем, эквивалент, ClassA нужно использовать EntityManager сохраняться некоторые данные, в то же время мой ClassB на самом деле интерфейс, поэтому мне нужно быть в состоянии решить во время выполнения, для реализации которого необходимо создать экземпляр в ClassC. Может быть, есть другие способы сделать это?

+0

Вы не можете создать экземпляр EJB с «новыми» ключевыми словами, это не вариант. Чтобы отнести к классу ejb, вы либо сделали контейнер, либо загрузили через JNDI. Каждый выбор имеет свой смысл, который вы используете на другом или другом подходе в зависимости от контекста. – Leonardo

ответ

1

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

Это очевидно, поскольку зависимости впрыскиваются контейнером. Поэтому, если вы создаете экземпляр и не устанавливаете какое-либо значение для зависимости, тогда зависимость будет null. С другой стороны, когда экземпляры создаются контейнером, он также устанавливает значения его зависимостей.

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

Да, это правильно. При создании экземпляра экземпляр поэтому не управляется.

Давайте предположим, что у нас есть такая настройка, это было бы возможно создать экземпляр (в явном виде) ClassB в ClassC и имеют ClassB вызвать метод из ClassA без бросать NullPointerException?

Нет, при создании экземпляра зависимости будут пустыми.

Поэтому я смотрю на него, потому что я в моем, эквивалент, ClassA нужно использовать EntityManager сохраняться некоторые данные, в то же время мой ClassB на самом деле интерфейс, так что я должен быть в состоянии для решения во время выполнения, для реализации которой необходимо создать экземпляр в ClassC. Может быть, есть другие способы сделать это?

Если вам нужно ввести конкретную реализацию, вы можете это сделать, указав имя бина.

@EJB(beanName="DefaultService") 
private Service defautService; 

@EJB(beanName="SpecificService") 
private Service specificService; 

Обратитесь к этой ссылке: http://www.adam-bien.com/roller/abien/entry/injecting_different_implementations_into_an

В качестве альтернативы, если вы используете CDI вы можете использовать @Qualifier

0

Другой способ получить ссылку EJB, если вы не можете использовать инъекцию, - это использовать JNDI для поиска.

Context initialContext = new InitialContext(); 
ClassB b = (ClassB)initialContext.lookup("java:global/yourappname/ClassB!com.package.containing.ClassB"); 

Таким образом, вы можете использовать любую логику вам нужно определить имя JNDI фактической реализации ClassB вам нужно, а затем посмотреть его.

+0

Это довольно аккуратно, я абсолютно попробую и прочитаю о JNDI, я верю! Я также нашел [этот ответ] (http://stackoverflow.com/a/7923159/2671179) к аналогичному вопросу. Не могли бы вы прокомментировать различия между подходами. То есть, какие соображения следует использовать при использовании JNDI vs a \ @singleston \ @startup "класса производителя"? –

+0

JNDI lookup - это «старомодный» способ получить доступ к EJBs, DataSources и т. Д. В общем, это PITA, потому что вы должны обрабатывать исключения и тип корректно выдавать результат. Вы бы использовали только JNDI, если нет возможности использовать инъекцию контейнера (что почти никогда не выполняется во время выполнения Java EE 7). –

 Смежные вопросы

  • Нет связанных вопросов^_^