Lecture14 (Лекции по Технологии программирования. Компонентный подход), страница 2
Описание файла
Файл "Lecture14" внутри архива находится в папке "Лекции по Технологии программирования. Компонентный подход". PDF-файл из архива "Лекции по Технологии программирования. Компонентный подход", который расположен в категории "". Всё это находится в предмете "основы программной инженерии" из 6 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 2 страницы из PDF
Соответственно, его методы поиска илисоздания возвращают ссылку на локальный интерфейс компонента или коллекцию такихссылок.Должен наследовать интерфейсу javax.ejb.EJBLocalHome.Класс компонента (bean class).Этот класс реализует методы удаленного и локального интерфейсов (но не долженреализовывать сами эти интерфейсы!). Он определяет основную функциональностькомпонента.Для компонентов данных такой класс должен быть абстрактным классом, реализующиминтерфейс javax.ejb.EntityBean.
Свойства, соответствующие полям хранимых данныхили ссылкам на другие компоненты данных, должны быть определены в виде абстрактныхпар методов getName()/setName(). В этом случае EJB-контейнер может взять на себяуправление синхронизацией их значений с базой данных. Вычислимые свойства, значениякоторых не хранятся в базе данных, реализуются в виде пар неабстрактных методов.Для сеансовых компонентов класс компонента должен быть неабстрактным классом,реализующим интерфейс javax.ejb.SessionBean и все методы удаленного и локальногоинтерфейсов.Кроме того, класс компонента может (а иногда и должен) реализовывать некоторыеметоды, которые вызываются EJB-контейнером при переходе между различными этапамижизненного цикла компонента.Например, при инициализации экземпляра компонента всегда вызывается методejbCreate().
Для компонентов данных он принимает на вход и возвращает значение типапервичного ключа компонента. Если первичный ключ — составной, он должен приниматьна вход значения отдельных его элементов. Такой метод для компонента данных долженвозвращать null и всегда должен быть реализован в классе компонента. Для сеансовыхкомпонентов он имеет тип результата void, а на вход принимает какие-то параметры,служащие для инициализации экземпляра компонента.
Для каждого метода исходныхинтерфейсов с именем createSomeSuffix(…) в классе компонента должен быть реализованметод ejbCreateSomeSuffix(…) с теми же типами параметров. Для компонентов данныхвсе такие методы возвращают значение типа первичного ключа, для сеансовых — void.Другие методы жизненного цикла компонента, которые можно перегружать в классекомпонента, декларированы в базовых интерфейсах компонентов соответствующего вида(javax.ejb.EntityBean или javax.ejb.SessionBean).
Это, например, ejbActivate() иejbPassivate(), вызываемые при активизации и деактивизации экземпляра компонента;ejbRemove(), вызываемый перед удалением экземпляра компонента из памяти; длякомпонентов данных — ejbStore() и ejbLoad(), вызываемые при сохранении данныхэкземпляра в базу приложения или при их загрузке оттуда.Схема жизненного цикла компонента данных показана на Рис. 75.Сеансовые компоненты могут поддерживать состояние сеанса, обеспечивая пользователювозможность получения результатов очередного запроса с учетом предшествовавшихзапросов в рамках данного сеанса, или не поддерживать.
Во втором случае компонентреализует обработку запросов в виде чистых функций.Жизненный цикл сеансового компонента различается в зависимости от того, поддерживаетли компонент состояние сеанса или нет.НесуществуетClass.newInstance()setEntityContext()Object.finalize ()unsetEntityContext()В пулеejbCreate()ejbPostCreate()ejbPassivate()ejbRemove()ejbActivate()АктивенejbLoad()обычные методыejbStore()Рисунок 75. Жизненный цикл EJB компонента данных.Схема жизненного цикла сеансового компонента с состоянием показана на Рис. 76.Отличие от жизненного цикла компонента данных единственное — метод ejbCreate()сразу переводит компонент в активное состояние.НесуществуетejbRemove()Class.newInstance()setSessionContext()ejbCreate()тайм-аутили исключениеejbPassivate()АктивенПассивенejbActivate()обычные методыРисунок 76.
Жизненный цикл сеансового компонента с состоянием.•Жизненный цикл сеансового компонента без состояния гораздо проще. Его схемапредставлена на Рис. 77.Класс первичного ключа (primary key class).Декларируется только для компонентов данных, если в этом качестве нельзя использоватьподходящий библиотечный класс.Определяет набор данных, которые образуют первичный ключ записи базы данных,соответствующей одному экземпляру компонента.Чаще всего это библиотечный класс, например, String или Integer.
Пользовательскийкласс необходим, если первичный ключ составной, т.е. состоит из нескольких значенийпростых типов данных. В таком классе должен быть определен конструктор без параметрови правильно перегружены методы equals() и hashCode(), чтобы EJB-контейнер могкорректно управлять коллекциями экземпляров компонентов с такими первичнымиключами.
Такой класс также должен реализовывать интерфейс java.io.Serializable.НесуществуетClass.newInstance()setSessionContext()ejbCreate()ejbRemove()Активенобычные методыРисунок 77. Жизненный цикл сеансового компонента без состояния.Ниже приведены примеры декларации класса компонента и интерфейсов для компонентовданных, соответствующих простой схеме из двух таблиц, которая изображена на Рис. 78.В рамках этой схемы, состоящей из таблиц, где хранятся данные книг и организацийиздателей, каждая книга связана с одним и только одним издателем, а каждый издатель можетиметь ссылки на некоторое множество книг (возможно, пустое). Каждая таблица имеет поле ID,являющееся первичным ключом.
Таблица Book имеет поле PublisherID, содержащее значениеключа записи об издателе данной книги.BookPublisherID : intTitle : StringISBN : StringPublisherID : intID : intTitle : StringРисунок 78. Пример схемы БД.Примеры кода удаленных интерфейсов для компонентов, представляющих данные о книгах ииздателях в рамках EJB-приложения.package ru.msu.cmc.prtech.examples;import java.rmi.RemoteException;import java.util.Collection;import javax.ejb.EJBObject;public interface PublisherRemote extends EJBObject{public String getTitle ()throws RemoteException;public voidsetTitle (String title) throws RemoteException;public Collection getBooks ()throws RemoteException;public voidsetBooks (Collection books)throws RemoteException;public void addBook(String title, String isbn)throws RemoteException;public void removeBook (String title, String isbn)throws RemoteException;}package ru.msu.cmc.prtech.examples;import java.rmi.RemoteException;import javax.ejb.EJBObject;public interface BookRemote extends EJBObject{public String getTitle ()throws RemoteException;public voidsetTitle (String title) throws RemoteException;public String getISBN ()throws RemoteException;public voidsetISBN (String isbn) throws RemoteException;public PublisherRemote getPublisher () throws RemoteException;public voidsetPublisher (PublisherRemote publisher)throws RemoteException;}Примеры кода удаленных исходных интерфейсов.package ru.msu.cmc.prtech.examples;import java.rmi.RemoteException;import javax.ejb.CreateException;import javax.ejb.EJBHome;import javax.ejb.FinderException;public interface PublisherHomeRemote extends EJBHome{public PublisherRemote create (Integer id)throws CreateException, RemoteException;public PublisherRemote findByPK (Integer id)throws FinderException, RemoteException;}package ru.msu.cmc.prtech.examples;import java.rmi.RemoteException;import javax.ejb.CreateException;import javax.ejb.EJBHome;import javax.ejb.FinderException;public interface BookHomeRemote extends EJBHome{public BookRemote create (Integer id)throws CreateException, RemoteException;public BookRemote createBook (String title, String isbn)throws CreateException, RemoteException;public BookRemote findByPK (Integer id)throws FinderException, RemoteException;}Примеры кода классов компонентов.
Показано, как реализовывать дополнительные, неподдерживаемые контейнером автоматически, методы работы со связями между данными обиздателях и книгах и дополнительные методы создания компонентов.package ru.msu.cmc.prtech.examples;import java.util.Collection;import java.util.Iterator;importimportimportimportimportjava.rmi.RemoteException;javax.ejb.CreateException;javax.ejb.EntityBean;javax.naming.InitialContext;javax.naming.NamingException;public abstract class PublisherBean implements EntityBean{public Integer ejbCreate (Integer pk){setId(pk);return null;}public void ejbPostCreate (Integer pk) { }public abstract Integer getId ();public abstract voidsetId (Integer pk);public abstract String getTitle ();public abstract voidsetTitle (String title);public abstract Collection getBooks ();public abstract voidsetBooks (Collection books);public void addBook (String title, String isbn){try{InitialContext context = new InitialContext();BookHomeRemote bookHome =(BookHomeRemote)context.lookup("BookHomeRemote");BookRemote book = bookHome.createBook(title, isbn);Collection books = getBooks();books.add(book);}catch (NamingException e) { e.printStackTrace(); }catch (CreateException e) { e.printStackTrace(); }catch (RemoteException e) { e.printStackTrace(); }}public void removeBook (String title, String isbn){Collection books = getBooks();Iterator it = books.iterator();try{while(it.hasNext()){BookRemote book = (BookRemote)it.next();if(book.getTitle().equals(title)&& book.getISBN().equals(isbn)){it.remove();break;}}}catch (RemoteException e) { e.printStackTrace(); }}}package ru.msu.cmc.prtech.examples;import javax.ejb.EntityBean;public abstract class BookBean implements EntityBean{public Integer ejbCreate (Integer pk){setId(pk);return null;}public void ejbPostCreate (Integer pk) { }public Integer ejbCreateBook (String title, String isbn){setTitle(title);setISBN(isbn);return null;}public void ejbPostCreateBook (String title, String isbn) { }public abstract Integer getId ();public abstract voidsetId (Integer pk);public abstract String getTitle ();public abstract voidsetTitle (String title);public abstract String getISBN ();public abstract voidsetISBN (String isbn);public abstract PublisherRemote getOrganization ();public abstract voidsetOrganization (PublisherRemote pr);}Компоненты, управляемые сообщениямиКомпоненты, управляемые сообщениями, не доступны для удаленных вызовов, и поэтому неимеют удаленных и исходных интерфейсов.