КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
EJB-программирование
Всю внешнюю информацию EJB получает от соответствующего контейнера. Если элементу EJB требуется получить доступ к JDBC-соединению или к другому bean, он обращается к службам контейнера. Доступ к индивидуальности вызывающего элемента, получение ссылки на самого себя, обращение к свойствам — все эти операции проводятся с помощью служб контейнера. Это наглядный пример тактики «введение посредника». Взаимодействие bean с контейнером обеспечивают три механизма: методы обратного вызова, интерфейс EJBContext, а также Java-интерфейс именования и каталогов Java Naming and Directory Interface, JNDI). Для создания серверного компонента EJB разработчику нужны два интерфейса, определяющие бизнес-методы bean, а также класс с его реализацией. Два упомянутых интерфейса — remote и home — показаны на рис. 16.5. С их помощью клиенты обращаются к bean внутри EJB-контейнера. Они показывают возможности bean и предоставляют все методы, необходимые для его создания, обновления, взаимодействия или удаления.
Эти интерфейсы, по существу, принадлежат к двум разным категориям, выполняющим различные задачи. Интерфейс категории «home» (будем называть его home-интерфейсом) содержит методы жизненного цикла EJB, обслуживающие клиентов no части создания, уничтожения и поиска экземпляров bean. Интерфейс категории «remote» (будем называть его remote-иитерфейсом), в свою очередь, содержит предоставляемые bean бизнес-методы. Все эти методы носят прикладной характер. Для того чтобы обращаться к ним через remote-интерфейс, клиенты должны с помощью home -интерфейса получить ссылку на него. Элементарный home-интерфейс приводится в листинге 16.1. Наследующий от интерфейса EJBHome, в данном случае он содержит метод создания EJB типа Broker. Листинг 16.2 содержит код remote-интерфейса EJB типа Broker. Remote-интерфейсы расширяют интерфейс EJBObject, который включает в себя ряд методов, применяемых контейнером для управления созданием и жизненным циклом элемента EJB. Программист волен делать выбор между принятием стандартного, унаследованного поведения и созданием для EJB индивидуального поведения. Впоследствии при помощи интерфейсов категории pubLic клиент создает, управляет и удаляет beans с EJB-сервера. Класс реализации, называемый обычно bean-классом, становится доступным распределенным объектам после конкретизации в период прогона. Несколько упрощенный пример клиентского кода приводится в листинге 16.3. Листинг 16.1. Простой home-интерфейс public interface BrokerHome extends EJBHome { /* Этот метод создает EJB Object. * * Qreturn только что созданный EJB Object. */ Broker create() throws RemoteException, CreateException; } Листинг 16.2. Remote-интерфейс брокера public interface Broker extends EJBObject { // Возврат только что созданного номера счета public int newAccount(String sub_name, String sub_address, int sub_credit) throws RemoteException, SQLException; public QueryResult queryStockValueByID(int stock_id) throws RemoteException. SQLException; public void buyStock(int sub_accno, int stock_id, int amount) throws RemoteException, SQLException, TransDenyException; public void sellStock(int sub_accno, int stock_id, int amount) throws RemoteException, SQLException, TransDenyException; publicvoid updateAccount(int sub_accno, int sub_credit) throws RemoteException, SQLException; public Vector getHoldingStatement(int sub_accno, int start_ stock_id) throws RemoteException, SQLException; } В качестве клиентов EJB могут выступать автономные приложения, сервлеты, апплеты и даже (в чем вы вскоре сможете убедиться) другие элементы EJB. Для получения ссылки на экземпляр серверного bean все клиенты обращаются к его home-интерфейсу. Ссылка эта ассоциирована с типом класса remote-интерфейса серверного bean; таким образом, взаимодействие клиента с серверным bean осуществляется исключительно теми методами, которые определены в его remote- интерфейсе. В следующем примере участвует сеансовый bean без состояния Broker, обрабатывающий все клиентские запросы. Внутрение, для осуществления бизнес-логики он обращается к службам ряда beans-сущностей. Пример одного из методов компонента Broker — updateAccount — показан в листинге 16. 4. Метод updateAccount использует bean-сущность под именем Account. Последняя инкапсулирует все детали обработки данных приложения — в данном случае процедуру обновления записи счета. Код метода updateAccount обращается к finder- методу с именем findByPrimaryKey, содержащемуся в Ьоте-интерфейсе bean-сущности Account. Принимая первичный ключ счета, этот метод обращается к соответствующей базе данных. Если первичного ключа оказывается достаточно для обнаружения в базе данных нужной записи счета, EJB-контейнер создает bean- сущность Account. Методы bean-сущности — в данном случае update — впоследствии обеспечивают доступ к данным в записи счета. Интерфейсы категорий home и remote bean-сущности Account показаны в листинге 16.5. Листинг 16.3. Упрощенный пример клиентского кода EJB Broker broker = null; // Поиск интерфейса home Object _h = ctx.lookup("EntityStock.BrokerHome"); BrokerHome home = (BrokerHome) javax.rmi.PortableRemoteObject.narrow(_h, BrokerHome.class); // Создание Broker EJB Object с помощью интерфейса home broker = home.createn: // Исполнение запросов на брокере EJB broker.updateAccount(accountNo, 200000); broker.buyStock(accountNo, stockID, 5000); // Готово.... broker.remove(); Листинг 16.4. MeTOflupdateAccountbean-компонента Broker public void updateAccount(int sub_accno, int sub_credit) throws RemoteException { try { Account account = accountHome.findByPrimaryKey (new AccountPK(sub_accno)); account.update(sub_credi t); } catch (Exception e) { throw new RemoteException(e.toString()); } } За реализацию удаленных (remote) методов отвечает bean -класс bean-сущности. Код метода update приводится в листинге 16.6. Он очень простой — фактически, он ограничивается одной-единственной строкой исполняемого кода Java. Такая простота достигается за счет применения данной bean-сущностью устойчивости с контейнерным управлением (container-managed persistence). EJB-контейнер «знает» (в этом вы скоро убедитесь) о соответствии между элементами данных в bean Account и полями в таблице счета из базы данных, к которой обращается приложение. С помощью этой информации инструментальные средства контейнера генерируют SQL-запросы, необходимые для реализации finder-метода, а также другие запросы, обеспечивающие автоматизацию записи/считывания данных из/ в bean-сущность в начале/конце транзакции. В нашем примере в конце метода updateAccount сеансового bean Broker элементы данных в bean-сущности Account записываются обратно в базу данных, обеспечивая тем самым устойчивый характер изменений в поле sub_credit. Все эти операции проводятся без явного контроля со стороны программиста, что свидетельствует о простоте построения систем на основе EJB. Листинг 16.5. Интерфейсы категорий home и remote bean-сущности Account public interface AccountHome extends EJBHome { /* * Этот метод создает EJB Object. * * @param sub_name Имя подписчика * @param sub_address Адрес подписчика * Фрагат sub_credit Начальный взнос подписчика * * Greturn Только что созданный EJB Object. */ public Account create(String sub_name, String sub_address, int sub_credit) throws CreateException. RemoteException; /* * Поиск Account по его первичному ключу (Account ID) */ public Account findByPrimaryKey(AccountPK key) throws FinderException, RemoteException; } public interface Account extends EJBObject { public void update(int amount) throws RemoteExcept1on; publ1c void deposit(int amount) throws RemoteException; publ1c int wi thdraw<int amount) throws AccountException, RemoteException; // Методы «получатель» и «установщик» в полях Entity Bean public int getCredit() throws RemoteException; public String getSubName() throws RemoteException; public void setSubName(String name) throws RemoteException; } Листинг 16.6. Метод update beam-сущности Ассount public class AccountBean implements EntityBean { // Поля состояния под управлением контейнера public int sub_accno; public String sub_name; public String sub_address; public int sub_credit; // Тут много чего пропущено... public void update(int amount) { sub_credit = amount; } } Дескрипторы размещения Одним из наиболее заметных преимуществ модели EJB является заложенный в ней механизм разделения задач между бизнес-логикой и кодом инфраструктуры — пример применения тактики «семантическая связность». Такого рода разделение связано с тем, что элементы EJB в основном содержат бизнес-логику, в то время как EJB-контейнеры отвечают за вопросы среды и инфраструктуры — транзакции, управление жизненным циклом bean и безопасность. В результате bean-компоненты упрощаются — перечисленные сложности в их коде не отражены. Для оповещения контейнера о службах, которые ему требуются, bean пользуется дескриптором размещения. Так называется связанный с EJB XML-документ. При размещении bean в контейнере последний считывает дескриптор размещения и из его содержания узнает задачи по обработке транзакций, устойчивости (для beans-сущностей) и управлению доступом. Таким образом, дескриптор есть декларативный механизм обработки перечисленных аспектов и в этом смысле являет собой пример применения тактики «откладывание времени связывания». Прелесть этого механизма в том, что один и тот же EJB-компонент, в зависимости от прикладной среды, размещается с разными дескрипторами. Если существенное значение имеет безопасность, компонент обозначает свои потребности по части управления доступом. Если безопасность Не имеет значения, управление доступом не специфицируется. В обоих случаях применяется одинаковый код EJB. Дескриптор размещения составляется в предопределенном формате, которого все EJB-совместимые beans должны придерживаться, а EJB-совместимые серверы — уметь считывать. Формат этот задается в виде XML-шаблона DTD (Document Typc Definition, описание типа документа). Дескриптор размещения описывает тип bean (сеансовый или сущность), классы для обеспечения интерфейсов remote и home, а также Ьеап-класс. Кроме того, он определяет транзактные свойства всех методов bean, роли безопасности, имеющие право доступа к тому или иному методу (управление доступом), а также устанавливает один из вариантов устойчивости — ее автоматическое обеспечение средствами контейнера или явное выполнение в коде bean. Дескриптор размещения рассмотренного ранее bean Broker представлен в листинге 16.7. Помимо описания свойств, этот дескриптор идентифицирует данный bean как сеансовый без состояния и сообщает о том, что для исполнения каждого из его методов необходима транзакция с контейнерным управлением (на листинге эти свойства для простоты выделены полужирным начертанием). К примеру стоит лишь ввести в поле <session-type> XML значение stateful, и контейнер будет управлять bean совершенно по-другому. В листинге 16.8 приводится дескриптор размещения bean-сущности Account. В дополнение к уже упомянутым свойствам размещения этот дескриптор сообщает контейнеру следующие сведения: ♦ для beans данного типа требуется управление устойчивостью; ♦ местонахождение источника данных JDBC для базы данных; ♦ отображение отдельных первичных ключей и элементов данных между базой данных и bean-сущностью. Листинг 16.7. Описание размещения bean Broker <ejb-jar> <enterprise-beans> <session> <ejb-name>EntityStock.BrokerHome</ejb-name> <home>j2ee.entitystock.BrokerHome</home> <remote>j2ee.entitystock.Broker</remote> <ejb-class>j2ee.enti tystock.BrokerBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>EntityStock.BrokerHome</ejb-name> <method-intf>Remote</method-intf> <method * name>*</method-name> </method> <trans-attri bute>Requi red</trans-attribute> </container•transacti on> </assembly-descriptor> </ejb-jar> Листинг 16.8. Описаниеразмещения Ьеап-сущностиАссоип1 <ejb-jar> <enterprise-beans> <entity> <ejb-name>EntityStock.AccountHome</ejb-name> <home>j2ee.enti tystock.AccountHome</home> <remote>j2ee,entitystock.Account</remote> <ejb-class>j2ee.entitystock.AccountBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key*class>j2ee.entitystock.AccountPK</prim*key-class> <reentrant>False</reentrant> <cmp-field> <field-name>sub_accno</field-name> </cmp-field> <cmp-field> <field-name>sub_name</field-name>, </cmp-field> <cmp-field> <field-name>sub_address</field-name> </cmp-field> <cmp-field> <field-name>sub_credit</field-name> </cmp-field> <resource-ref> <res-ref-name>jdbc/sqlStock_nkPool</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </entity> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>EntityStock.AccountHome</ejb-name> <method-i ntf>Remote</method-i ntf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> В табл. 16.2 мы перечислили требования по атрибутам качества, которые компания Sun предъявляетк^ЕЕ. В табл. 16.5 мы обозначаем механизм реализации этих требований посредством дескрипторов размещения.
16.4. Решения по размещению системы Все, о чем мы говорили выше, справедливо по отношению к спецификациям^ЕЕ/ EJB по версии Sun. Существует также ряд проблем реализации, которые архитектор в процессе размещения системы J2EE/EJB должен решить. Компонентная.модель EJB — это мощный инструмент конструирования серверных приложений. Поначалу взаимосвязи между различными частями кода сбивают с толку, однако, если разобраться и наработать некоторый опыт, становится ясно, что конструировать EJB-приложения не так уж и сложно. Впрочем, несмотря на удобство кодирования, есть ряд сложностей, которые нужно уметь разрешать. ♦ Модель EJB позволяет комбинировать компоненты приложения в соответствии с разными архитектурными образцами. Какие из них лучше и что значит «лучше» в контексте конкретного приложения? ♦ Механизм взаимодействия beans с контейнером довольно сложен, а кроме того, он оказывает значительное воздействие на производительность приложения. Кроме того, серверные контейнеры EJB отличаются один от другого — таким образом, довольно значимыми становятся такие аспекты жизненного цикла разработки приложения, как отбор продуктов и конфигурирование конкретного продукта. В завершающем разделе мы представим обзор основных проектных проблем, возникающих в процессе создания архитектуры и конструирования сверхмасш- табируемых EJB-приложений. Управление состоянием — старая проблема в новом контексте При разработке серверного звена EJB встает вопрос о принятии одной из двух моделей обслуживания: без запоминания состояния (stateless) и с запоминанием состояния (stateful), реализуемых сеансовыми beans без состояния и сеансовыми beans с запоминанием состояния соответственно. Для примера рассмотрим сетевой книжный магазин. В версии с запоминанием состояния EJB можно заставить сохранять детальные данные о покупателе н управлять товарами, который он помещает в интерактивную корзину. Таким образом, EJB будет хранить состояние, связанное с посещением сайта данным покупателем. Поскольку bean сохраняет состояние диалога, клиент может за ним не следить. EJB отслеживает потенциальные покупки и при вызове метода подтверждения осуществляет их пакетную обработку. В целях оптимизации использования ограниченных ресурсов системной памяти невостребованные клиентами сеансовые beans с запоминанием состояния пассивируются — иначе говоря, состояние диалога bean записывается на вспомогательное запоминающее устройство (как правило, на диск), а экземпляр, хранящийся в памяти, удаляется. Ссылка на bean у клиента при пассивации остается активной и готовой к употреблению. Когда клиент вызывает метод в пассивированном bean, контейнер запускает новый экземпляр bean и наполняет его состояние информацией, записанной на вспомогательное ЗУ. Стратегия пассивации оказывает значительное влияние на масштабируемость. Если для обслуживания отдельных клиентов постоянно пассивируются и активируются многочисленные экземпляры сеансовых beans с запоминанием состояния, издержки производительности приложения могут очень сильно возрасти. Сеансовый bean без состояния не принимает на себя обязательства rio сохранению клиентского состояния диалога. При каждом запросе на обслуживание клиенту приходится информировать сервер о состоянии сеанса — в частности, сообщать свои данные и содержимое корзины; такая необходимость связана с тем, что на каждый запрос контейнер может выделять разные экземпляры сеансового bean без состояния. В рамках простой модели обслуживания без запоминания состояния это единственно возможный вариант. Механизм использования сеансовых beans с запоминанием и без запоминания состояния изображен на рис. 16.6. Обобщенно преимущества сеансовых beans без состояния можно сформулировать следующим образом: ♦ Издержки производительности, связанные с пассивацией и активацией сеансовых beans, а следовательно, и с проведением дорогостоящих операций записи и считывания на диск, отсутствуют. ♦ Благодаря динамической маршрутизации запросов эти самые запросы перенаправляются на наименее загруженный сервер. ♦ В случае недоступности экземпляра сеанса запрос оперативно перенаправляется другому экземпляру. Единственный недостаток методики незапоминания состояния состоит в том, что при каждом запросе между клиентом и EJB передается информации больше, чем обычно. Если предположить, что передаваемые данные не слишком объемны, то, скорее всего, степень масштабируемости системы в случае применения сеансового bean без запоминания состояния все-таки окажется выше.
Дата добавления: 2015-04-25; Просмотров: 705; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |