Главная » Java, JavaBeans » Пример создания приложения с stateless Session- компонентом

0

В качестве первого знакомства с Контейнерами и Компонентами EJB, мы создадим простое клиент-серверное приложение, называемое SortClient, которое выполняет сортировку. Этот пример использует алгоритм сортировки слиянием. Задача – демонстрация основных шагов по созданию и компиляции Компонента с последующим запуском в Контейнере EJB. Пример также демонстрирует использование RMI-IIOP и взаимодействие объектов с помощью службы имен JNDI.

Сначала мы объясним, зачем нужен тот или иной фрагмент кода. Обычно написание кода, реализующего функциональность Компонента – это задача bean provider’a. Весь текст уже содержится в примере sort, поэтому ничего заново писать не придется. Затем мы покажем, как откомпилировать и построить Компонент, упаковать его, выполнить его поставку, создать приложение-клиент и, наконец, запустить его.

Для создания нашего простого приложения необходимо выполнить следующие шаги:

1         Написать код Компонента. Сюда входит написание собственно кода Компонента и его remote- и Ьоте-интерфейсов.

2         Откомпилировать и построить Компонент и его клиента.

3         Создать Дескриптор Поставки в каталоге META-INF.

4         Упаковать Компонент.

5         Поместить Компонент в JAR-файл.

6         Запустить приложение-клиент.

Написание Компонента

Для каждого Компонента EJB существуют три составляющих, и разработчик (bean provider) должен их написать. Это следующие части:

•          Класс реализации – Это класс Компонента EJB. Он реализует бизнес- логику Компонента и функциональность, определяемую его home- и remote-интерфейсами. В нашем примере этот класс называется SortBean.java.

•          Интерфейс Ноте – он определяет операции создания, поиска и уничтожения Компонента. Он играет роль Фабрики Объектов, если использовать принятую для распределенных систем терминологию. Имя этого интерфейса для нашего Компонента – SortHome.

•          Интерфейс Remote – он определяет доступные для клиента бизнес- методы Компонента. Имя этого интерфейса в нашем примере – Sort.

Для того, чтобы клиент мог взаимодействовать с Компонентом EJB, вы должны написать все эти три составные части. Клиентское приложение использует home-интерфейс Компонента для поиска и получения ссылки на его remote-интерфейс. После получения такой ссылки, клиент может обращаться к любому методу remote-интерфейса. Клиент не знает, является этот метод локальным или удаленным. С точки зрения клиента, вызов удаленного метода Компонента EJB выглядит так же просто, как вызов любого локального метода. Контейнер EJB передает вызов клиента настоящему (и невидимому для клиента) экземпляру Компонента, используя необходимый комуникационный протокол, а затем возвращает результат вызова клиенту через remote- интерфейс.

На Рис. 3.1 показано, что происходит, когда клиентское приложение SortClient обращается к методу merge () Компонента SortBean. Обратите внимание, что клиент сначала вызывает метод create () интерфейса SortHome. Результатом вызова является ссылка на интерфейс Sort. После этого клиент вызывает метод merge () remote-интерфейса Sort, и этот вызов передается на выполнение соответствующему бизнес-методу Компонента SortBean.

Рис. 3.1 Флаги EJB сервера, необходимые для запуска примеров

В нашем примере Компонент является Session-Компонентом без состояния. Большинство Session-Компонентов состояние имеют – экземпляр Компонента создается в контексте сессии (или сеанса связи), и в продолжение всего сеанса экземпляр обслуживает запросы только этого клиента. По определению, stateful Session-Компонент сохраняет свое состояние, характеризующее его взамодействие с клиентом в продолжение всего сеанса.

С другой стороны, stateless Session-Компонент не предназначен для обслуживания вызовов только от одного клиента и не хранит состояние, оставшееся от обслуживания предыдущих вызовов. Когда клиент вызывает метод такого Компонента, Контейнер выбирает для обслуживания запроса любой экземпляр Компонента из пула. Компонент имеет определенное состояние, но только на время выполнения обслуживания одного вызова. После завершения обработки Компонент возвращает некоторый результат и не считается больше сопоставленным с конкретным клиентом. Контейнер сам решает, нужно или не нужно вернуть этот экземпляр Компонента в пул Компонентов.

Написание интерфейса home

Интерфейс home содержит методы для создания, поиска и уничтожения экземпляров Компонентов EJB. Ноте-интерфейс для Session- Компонента без состояния проще, чем для Session-Компонента с состоянием или для Entity-Компонента. Интерфейс SortHome наследует (extends) интерфейс javax.ejb.EJBHome и объявляет единственный метод – create (). Он не имеет аргументов и может возбуждать два типа исключений: RemoteException и CreateException.

Метод create () возвращает результат типа Sort; это и есть ссылка на remote-интерфейс нашего Компонента SortBean. Помните, что клиент не вызывает методы экземпляра Компонента непосредственно; вместо этого, клиент вызывает методы remote-интерфейса, поэтому метод create () и возвращает ссылку на этот интерфейс.

Session-Компоненты с состоянием и Entity-Компоненты, раз они могут поддерживать определенное состояние, могут предоставлять клиенту несколько методов для создания их экземпляров и могут требовать передачи некоторых параметров для выполнения инициализации экземпляра. Stateless Session-Компонент может иметь только один метод create (), причем без аргументов. Метод remove (), который удаляет экземпляр Компонента из пула, унаследован от интерфейса EBJHome, и от вас не требуется объявлять его в интерфейсе SortHome.

home-интерфейс для SortBean показан в Примере кода 3.1:

Пример кода 3.1 SortHome интерфейс

// SortHome java

public interface SortHome extends javax.ejb.EJBHome { Sort created throws java.rmi.RemoteException, j avax.ej b.CreateException;

}

Написание remote-интерфейса

Remote-интерфейс объявляет и делает доступным те методы Компонента, к которым может обращаться его клиент. Этот интерфейс наследует интерфейс javax.ejb.EJBObject.

Каждый метод, объявленный в интерфейсе Sort, должен иметь соответствующий метод в классе SortBean; методы должны иметь одинаковые имя и сигнатуры. Кроме того, методы remote-интерфейса Sort должны возбуждать исключение java.rmi.RemoteException и должны возвращать корректные типы RMI.

Remote-интерфейс Sort объявляет два метода: sort () и merge (). Оба могут возбуждать исключение java.rmi.RemoteException и оба возвращают тип Vector. Remote-интерфейс Sort для SortBean показан в Примере кода 3.2:

Пример кода 3.2 Sort интерфейс

// Sort java

import java.util.Vector;

public interface Sort extends javax.ejb.EJBObject {

Vector sort(Vector v, Compare c) throws java.rmi.RemoteException; Vector merge(Vector a, Vector b, Compare c) throws j ava.rmi.RemoteException;

}

Написание реализации Компонента

Так как SortBean является Session-Компонентом, он обязан реализовать интерфейс javax.ejb.SessionBean. Обратите также внимание на то, что класс SortBean объявлен как public.

Реализационный класс нашего Компонента определяет бизнес-методы, к которым может обращаться клиент. В нашем примере, класс SortBean содержит реализации методов sort () и merge (). К этим двум методам клиент будет обращаться при запуске нашего приложения. Заметьте, что сигнатуры этих методов совпадают с сигнатурами методов remote- интерфейса Sort.

Компонент реализует также метод ejbCreate (), который соответствует методу create () home-интерфейса. Ноте-интерфейс SortHome определяет единственный метод create () без аргументов, возбуждающий исключение java.rmi .RemoteException. Класс SortBean реализует метод ejbCreate () без аргументов и также возбуждающий исключение java.rmi.RemoteException. Тем не менее, в отличие от метода create () интерфейса SortHome, который возвращает объект типа Sort, метод ejbCreate () возвращает void.

Класс SortBean не имеет риЬНс-конструктора, хотя это и разрешено. SortBean объявляет четыре метода, помимо бизнес-методов и методов создания (create). Вот эти методы: ejbRemove() , ejbPassivate () , ejbActivate () и ejbSessionContext (). За реализацию этих методов отвечает Контейнер; класс SortBean должен просто их объявить как public-методы, возвращающие тип void.

Пример кода 3.3 содержит фрагмент кода класса SortBean. Для ясности не приведен код методов sort () и merge (); кроме того, не показаны некоторые отладочные операторы. Полный текст содержится в файле SortBean.java, находящемся в каталоге …\examples\sort.

Пример кода 3.3 Класс SortBean

// SortBean java import java util Vector;

public class SortBean implements javax.ejb.SessionBean {

public void setSessionContext(javax.ejb.SessionContext

sessionContext) {} public void ejbCreate() throws java.rmi.RemoteException {} public void ejbRemove() throws java.rmi.RemoteException {} public void ejbActivate() throws java.rmi.RemoteException {} public void ejbPassivate() throws java.rmi.RemoteException {}

public Vector sort(Vector v, Compare c) throws

java.rmi.RemoteException { try (

return result; }

catch(javax.ejb.CreateException e) {

throw new java.rmi.ServerException("Could not create

sort instance", e);

}

catch(javax.ejb.RemoveException e) {

throw new java.rmi.ServerException("Could not remove sort instance", e);

}

}

public Vector merge(Vector a, Vector b, Compare c) throws java.rmi.RemoteException {

}

}

Написание кода клиента

Первое, что должно выполнить клиентское приложение – это получить доступ к home-интерфейсу для Компонента SortBean. Делается это с помощью вызова методов JNDI API. Как показано в Примере 3.4, SortClient создает контекст имен JNDI, а затем использует его метод lookup для поиска home-интерфейса для "sort":

Пример кода 3.4 Фрагмент кода SortClient

// SortClient java

public class SortClient {

public static void main(String[] args) throws Exception { javax.naming.Context context;

{ // get a JNDI context using the Naming service context = new javax.naming.InitialContext ();

}

Object objref = (SortHome) context.lookup("sort"); SortHome home = (SortHome)

j avax.rmi.PortableRemoteObj ect.narrow(obj ref, SortHome.class); Sort sort = home.create(); … //do the sort and merge work sort.remove();

}

}

После получения ссылки на интерфейс SortHome, клиент может вызвать его метод create () для получения ссылки на remote-интерфейс Sort. Получив эту ссылку, клиент может вызывать его методы sort () и merge () так же, как он мог бы обращаться к любым другим методам. На самом деле remote-интерфейс перенаправляет вызовы клиента собственно Компоненту EJB.

Построение Компонента и клиентского приложения

Мы компилируем и строим как Компонент, так и его клиента, используя Маке-файл. Этот файл содержит все необходимые команды, а именно, обращается за выполнением требуемых действий к java2iiop, jar и verify.

Убедитесь, что ваши переменные среды – CLASSPATH и PATH – имеют правильные значения. См. раздел "Построение примеров" на стр. 111 для получения информации о том, как устанавливать значения этих переменных.

После того, как вы настроили переменные среды, откомпилируйте и постройте пример следующим образом:

Для Solaris:

prompt% make

Обратите внимание, что таке-файл требует наличия UNIX-совместимой утилиты make.

Для Windows:

prompt% make all

Маке-файлы достаточно просты, и вы можете редактировать их "вручную", если необходимо.

Содержимое таке-файла для примера sort показано ниже: Пример кода 3.5 таке-файл для примера sort

# Makefile

default: all

include ../Makefile rules

SRCS = \

SortClient.java \ \

Sort.java \ SortHome.java \ SortBean.java

CLASSES = $(SRCS:.java=.class)

beans jar: $(CLASSES) $(JAVA2II0P) SortHome $(JAR) cMf beans.jar META-INF *.class $(VERIFY) beans.jar

all: $(CLASSES) beans.jar

Создание Дескриптора Поставки

Дескриптор Поставки представляет собой XML-файл, который определяет атрибуты Компонента EJB. Для создания Дескриптора можно использовать любой XML-редактор; для модификации гораздо удобнее работать с Редактором Дескрипторов. Для простоты вы можете создавать свои Дескрипторы на базе Дескрипторов из примеров. Эти XML-файлы вы найдете в подкаталогах META-INF каталогов соответствующих примеров.

Внимание! При использовании стандартного XML-редактора вы сами должны

обеспечить соответствие требованиям спецификации EJB 1.1, и если вы хотите, чтобы ваш компонент мог быть помещен в EJB-Контейнер, вы должны использовать Inprise Document Type Definition (DTD).

Инфо В настоящий момент, вы должны использовать стандартный XML- редактор для создания Дескриптора Поставки. После того, как Дескриптор будет помещен в Jar-файл, вы можете для работы с ним использовать Редактор Дескриптора Поставки.

Дескриптор Поставки содержит информацию, необходимую для настройки Компонента; этим занимается Deployer.

Компоненты EJB предназначены для использования в различных приложениях без необходимости изменения их исходного кода. Но, поскольку каждое приложение использует некий универсальный Компонент по-своему, этот Компоненте необходимо настроить на взаимодействие с конкретным приложением – с помощью изменения свойств, хранящихся в Дескрипторе Поставки. Обратите внимание, что в Дескрипторе Компонента SortBean хранятся тип компонента (stateless session), имена его home-интерфейса (SortHome) и remote-интерфейса (Sort) и тип транзакции (container managed).

Подробное описание Дескриптора Поставки находится в Главе 9, "Поставка Enterprise JavaBeans".

Запуск примера Sort

Для того, чтобы выполнить пример, вы должны предварительно запустить Smart Agent для выполнения некоторых начальных действий – обеспечения возможности для клиента связаться со службой имен и др. (Smart Agent входит в комплект поставки Application Server).

Запустите EJB-Контейнер с помощью следующей команды:

prompt% vbj com.inprise.ejb.Container ejbcontainer sort beans.jar -jts -jns

Для просмотра описания синтаксиса и флагов команды, обратитесь к разделу "Основы Контейнера EJB и инструментальных средств" на стр. 3-7 .

Запустите клиентское приложение с помощью команды:

prompt% vbj SortClient Клиент выполняет поиск Компонента SortBean, а затем вызывает его методы для сортировки массивов переменной длины. Вы увидите ввод – строка, помеченная как "in" – и отсортированный выходной массив – строка, помеченная как "out" – на консоли. Результаты будут выглядеть примерно так:

in:     [1]

out:     [1]

in:     [1, 2]

out:     [1, 2]

in:     [1, 2, 7, 3, 8, 10, 4, 9, 5, 6]

out:     [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

in:     [-87, 91, 66, 85, -43, 29, 57, 57, 91, 22, -94, 55, 78, 50, 81,

15, -51, 26, 13, 27, -56, -35, 84, 89, -98]

out:     [-98, -94, -87, -56, -51, -43, -35, 13, 15, 22, 26, 27, 29, 50,

55, 57, 57, 66, 78, 81, 84, 85, 89, 91, 91]

in:     [-4, 8.0, 3.0, -6, -4, 4]

out:     [-6, -4, -4, 3.0, 4, 8.0]

in:     [this, is, a, test]

out:     [a, is, test, this]

Источник: Руководство программиста Enterprise JavaBeans

По теме:

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