Теперь, когда вы уже видели примеры сессионных EJB-компонентов и их различных интерфейсов, вам, возможно, хочется взглянуть на то, как клиент вызывает эти EJB-компоненты. Клиентом сессионного EJB-компонента может быть любой компонент: POJO, графический интерфейс (Swing), управляемый CDI MBean-компонент, сервлет, EJB-компонент JSF, являющийся подложкой, веб-служба (SOAP или REST) либо другой EJB-компонент (развернутый в том же или другом контейнере).

На стороне клиента также все просто. Чтобы вызвать метод в сессионном EJB-компоненте, клиент не создает экземпляр соответствующего EJB-компонента непосредственным образом (с использованием оператора new). Ему нужна ссылка на этот EJB-компонент (или на его интерфейсы). Он может получить ее при внедрении зависимостей (с использованием аннотации @EJB или @Inject) либо с помощью JNDI-поиска. Внедрение зависимостей позволяет контейнеру автоматически внедрять ссылку на EJB-компонент во время развертывания. Если не предусмотрено иное, то клиент будет вызывать сессионный EJB-компонент синхронно.

<p>Вызов с использованием внедрения</p>

Java EE задействует несколько аннотаций для внедрения ссылок на ресурсы (@Resource), менеджера сущностей (@PersistenceContext), веб-службы (@WebServiceRef) и т. д. Аннотация @javax.ejb.EJB специально предназначена для внедрения ссылок на сессионные EJB-компоненты в клиентский код. Внедрение зависимостей возможно только в управляемых средах вроде EJB-контейнеров, веб-контейнеров и контейнеров клиентских приложений.

Обратимся к нашим исходным примерам, в которых сессионные EJB-компоненты не обладали интерфейсом. Чтобы клиент смог вызвать представление без интерфейса сессионного EJB-компонента, ему необходимо получить ссылку на сам класс EJB-компонента. Например, в приведенном далее коде клиент получает ссылку на класс ItemEJB с использованием аннотации @EJB:

@Stateless

public class ItemEJB {…}

// Клиентский код с внедрением ссылки на EJB-компонент

@EJB ItemEJB itemEJB;

Если сессионный EJB-компонент реализует несколько интерфейсов, клиенту придется указать, на какой из них ему требуется ссылка. В приведенном далее коде ItemEJB реализует два интерфейса и благодаря аннотации @LocalBean также обеспечивает представление без интерфейса. Клиент может вызвать EJB-компонент с помощью его локального представления, удаленного представления или представления без интерфейса:

@Stateless

@Remote(ItemRemote.class)

@Local(ItemLocal.class)

@LocalBean

public class ItemEJB implements ItemLocal, ItemRemote {…}

// Клиентский код с внедрением нескольких ссылок на EJB-компонент или интерфейсы

@EJB ItemEJB itemEJB;

@EJB ItemLocal itemEJBLocal;

@EJB ItemRemote itemEJBRemote;

У API @EJB имеется несколько атрибутов. Один из них — JNDI-имя EJB-компонента, который вы хотите внедрить. Оно может быть особенно полезно при работе с удаленными EJB-компонентами, располагающимися на другом сервере:

@EJB(lookup = "java: global/classes/ItemEJB") ItemRemote itemEJBRemote;

<p>Вызов с использованием CDI</p>

Как вы только что видели, для вызова метода в EJB-компоненте требуется только аннотация @EJB, позволяющая внедрить ссылку в клиентский код. Все довольно просто: вы получаете ссылку во время развертывания. Однако @EJB не обеспечивает, например, чего-то подобного CDI-альтернативам. Взамен вам придется использовать аннотацию @Inject.

В большинстве случаев вы можете просто заменять @EJB аннотацией @Inject, и ваш клиентский код будет работать. Сделав это, вы получите все преимущества CDI, которые видели в главе 2. Таким образом, если мы обратимся к приведенным ранее примерам, то вот как обеспечивалось бы EJB-внедрение с использованием CDI в случае с клиентом:

@Stateless

@Remote(ItemRemote.class)

@Local(ItemLocal.class)

@LocalBean

public class ItemEJB implements ItemLocal, ItemRemote {…}

// Клиентский код с внедрением нескольких ссылок на EJB-компонент или интерфейсы посредством @Inject

@Inject ItemEJB itemEJB;

@Inject ItemLocal itemEJBLocal;

@Inject ItemRemote itemEJBRemote;

Перейти на страницу:

Похожие книги