Подтвердить что ты не робот

@Inject, @EJB, @Local, @Remote, @LocalBean и т.д.:: Confused?

У меня есть следующая конфигурация:

  • 1 EAR на одном GF, содержащем 2 EJB-JAR с компонентами EJB.
  • 1 WAR на другом сервере Glassfish (= > другой JVM), содержащий веб-компоненты, обращающиеся к компонентам EJB.

У меня есть 2 бизнес-службы EJB в каждом EJB-JAR моего EAR, и все они развиты следующим образом:

@Remote
public interface ServiceAItf {
    ...
}

@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
    ...
}

В моей WAR я обращаюсь к компонентам EJB через явный "InitialContext.lookup" на удаленном интерфейсе.

В моем EAR я совершенно смущен лучшей практикой для инъекций с точки зрения производительности, архитектуры и т.д....

У меня есть следующие вопросы:

  • Как вы можете видеть, я объявил аннотацию "@Local" в реализации службы без определения локального интерфейса. Правильно ли это? По крайней мере, у меня нет ошибки при развертывании. Но, может быть, я должен использовать аннотацию "@LocalBean" ? Я полагаю, что аннотация "@LocalBean" просто позволяет вызывать реализацию непосредственно как "Локальный" EJB, но вы должны использовать реализацию в своем коде следующим образом:

    @Stateless @Местный Открытый класс ServiceBImpl реализует ServiceBItf {   @EJB   частный сервис ServiceAImplA;   ... }

  • Каков наилучший способ вставить один EJB в другой? Он работает следующим образом:

    @Stateless @Местный Открытый класс ServiceBImpl реализует ServiceBItf {   @EJB   частная служба ServiceAItf;   ... }

Но из того, что я заметил, введенный "serviceA" - это удаленный прокси-сервер, в то время как он находится в одной JVM в одном и том же файле EAR. Поэтому я полагаю, что это повлияет на производительность. Вот почему я попытался ввести такую ​​услугу следующим образом:

@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
    @Inject
    private ServiceAItf serviceA;
    ...
}

Но это не работает в GF, у меня есть следующее исключение:

WELD-001408 Unsatisfied dependencies for type [...] ...

Затем я попытался создать локальный интерфейс, и инъекция через аннотацию "@Inject" работает, когда обе службы

Даже если я создаю локальный интерфейс, подобный этому, служба не вводится через аннотацию "@Inject" , но имеет значение null:

@Local
public interface ServiceALocalItf {
    ...
}

Я прочитал много статей, в которых настоятельно рекомендуется использовать "@Inject" вместо "@EJB" , когда он предназначен для локального вызова. Это приводит меня к следующему вопросу: в этом случае рекомендуется использовать (или просто использовать) вызов EbB "@Local" ?

После всего этого анализа я пришел к следующему выводу:

  • Для каждой службы я создаю интерфейс "@Local" и "@Remote" .
  • От WAR до EJB-JAR EAR, сделайте поиск JNDI на удаленном интерфейсе.
  • От EJB-JAR до EJB-JAR сделайте инъекцию через "@EJB" в локальный интерфейс.
  • Для двух служб внутри одного EJB-JAR выполните инъекцию через "@Inject" в локальный интерфейс.

Что вы думаете об этом? Правильно ли это?

4b9b3361

Ответ 1

Как вы можете видеть, я объявил аннотацию "@Local" на службе реализация без определения локального интерфейса. Правильно ли это?

С EJB 3.1 требование для локальных интерфейсов было отключено. Не нужно писать их, если они явно не нужны.

Каков наилучший способ вставить один EJB в другой?

Несколько вещей, чтобы написать здесь:

С Java EE 6, Java Enterprise изменилась. Новый JSR определяет так называемый управляемый bean (не путайте с управляемым JSF beans) как своего рода минимальный компонент, который все еще может извлечь выгоду из контейнера с точки зрения управления впрыском и управления жизненным циклом. Это означает: если у вас есть компонент и "просто" хотите использовать DI и позволить контейнеру контролировать его жизненный цикл, вам не нужно использовать EJB для него. В конечном итоге вы будете использовать EJB, если - и только если - вам явно нужны функции EJB, такие как обработка транзакций, объединение, пассивация и кластеризация.

Это дает ответ на ваш вопрос в трех частях:

  • Используйте @Inject over @EJB, концепция CDI (a) работает для всех управляемых beans (сюда входят EJB), и (b) является состоятельным и, следовательно, далеко превосходит чистый @EJB DI
  • Вы уверены, что вам нужны EJB для вашего компоненты?
  • Конечно, стоит взглянуть на CDI .

Ответ 2

@Inject аннотация используется для java beans (POJO), а аннотация @EJB используется для корпоративного java beans. Когда контейнер вводит ejb, предоставленный аннотацией @EJB к другому bean, он также управляет этим жизненным циклом ejb, выполняет объединение для безстоящих beans и т.д. (Когда bean, который будет инъецирован, не разворачивается ссылка будет null). Если вы используете механизм @Inject annotation CDI, просто найдите и создайте экземпляр инжектируемого ресурса, например, с новым оператором (если реализация интерфейса, который будет введена, не существует, ссылка будет пустой). Вы можете использовать квалификаторы с аннотацией @Inject для выбора различной реализации внедренного интерфейса.