Мы знаем, что EJB суть компоненты. Однако, термин "компонент" один из наиболее перегруженных в индустрии, и разные люди (и разные поставщики) имеют разные идеи о том, что такое компонент. Для платформы .NET от Microsoft компонент является чем-то, что компилируется с (D)COM(+) бинарной спецификацией, а природа и тип компонента определяется стандартными интерфейсами, которые он предоставляет. Однако, нет архитектурной модели, предписанной платформой Microsoft, или это преднамеренно не оговорено. Другими словами, существует очень мало предписанных архитектурных требований, которые говорят, как разрабатывать и собирать компоненты для создания промышленного приложения.
Платформа J2EE, с другой стороны, предоставляет вам более точную архитектуру рабочей среды, в которой вы создаете и используете компоненты. Это особенно верно для EJB, для которых спецификация определяет три разных EJB типа, с разными характеристиками отклика и разными областями применения. Вот эти три EJB типа:
- Entity Beans
- Session Beans
- Message-Driven Beans
Entity beans представляет объекты в том смысле, что Контейнер прозрачно хранит их состояния синхронно с данными в некотором другом постоянном хранилище, обычно это реляционная база данных. По этой причине entity beans используются для представления бизнес-сущностей, таких как клиент, корзина покупок и так далее. Entity beans не реализуют бизнес-логику, за исключением самосодержащейся логики напрямую связанной с внутренними данными. Хотя все entity beans открыты для клиентского кода одинаковым образом, они могут быть реализованы при использовании двух разных живучих стратегий. Разработчик имеет два варианты: 1) позволить Контейнеру заботиться о перемещении состояний между EJB объектом и базой данных, или 2) позаботиться об этом механизме и реализовать код, который перемещает состояние EJB от и к постоянному хранилищу. В первом случае мы говорим, что мы применяем Живучесть Управляемая Контейнером [Container Managed Persistence] (CMP), так что entity beans является CMP bean; во втором случае мы используем Живучесть Управляемая Компонентом [Bean Managed Persistence] (BMP), и мы получаем BMP bean. Опять таки, хотя есть существенное практическое отличие между CMP и BMP в стратегиях реализации, это не влияет на способ использования клиентом entity bean.
Обсуждения всех хитросплетений при предпочтении CMP перед BMP выходит за пределы этой главы. Однако важно объяснить, что большинство полезных свойств CMP не в том, как вы можете подумать, что вам не нужен код логики самосохранения. Реальная выгода от CMP состоит в том, что компонент может портироваться под любую систему постоянного хранения. Если вы думали об этом, CMP работает потому, что Контейнер генерирует весь код, необходимый для переноса состояния между EJB объектом и постоянным хранилищем. Это означает, что Контейнер знает, как взаимодействовать с таким специальным хранилищем. Реализация EJB Контейнера поддерживает различные хранилища, обычно все основные RDBMS, такие как Oracle, DB2, MySQL и т.п. Так как логика сохранения не закодирована жестко в CMP entity bean, а она предоставляется Контейнером, вы можете использовать тот же самый бинарный компонент в разных рабочих средах и все еще пользоваться поддержкой хранения объекта, предоставляемой Контейнером. Если вы используете BMP, логика хранения (например SQL выражения, если вы программируете для специфической RDBMS) будет встроена в ваш компонент, что затруднит использования другого хранилища.
Таким образом, вы используете CMP для того, чтобы повысить уровень портируемости; и вы используете BMP, если ваш entity bean связан с некоторой системой, не поддерживаемой платформой J2EE (например, это CICS приложение в IBM майнфрейме) или по другим особым причинам, которые мы не может предположить здесь.
Session beans по сути это другой род. Они не постоянны, и вместо дискретных компонентов, которые реализуют бизнес-логику, реализуют, например, шаги, требуемые для проверки и покупки некоторых продуктов в виртуальную корзину. Session beans могут взаимодействовать с другими session beans, чтобы получить доступ к дополнительной бизнес-логике, и они используют entity beans, когда им нужно получить доступ к хранимой информации. Session beans получаются в двух разных вариантах: session beans не имеющий состояний (Stateless session beans - SLSB) и session beans поддерживающие состояния (Stateful session beans - SFSB).
Различия между этими двумя типами в том, что session beans с поддержкой состояний хранит диалоговую информация во время обмена с клиентом, в то время, как session beans без поддержки состояний этого не делает. Диалоговая информация о состоянии - это информация, которая передается от клиента к session beans при последовательном вызове методов.
Например, вам нужен session beans, реализующий логику резервирования и покупки билетов в кино по сети. Клиенты должны подключиться и использовать один из экземпляров такого компонента; экземпляр должен предоставить два метода, reserveSeats(& ) и purchase(& ). Первый метод принимает количество мест, которые нужны покупателю для покупки, и резервирует их в системе; второй метод принимает информацию о кредитной карте покупателя, проверяет сумму на ней и выполняет процесс покупки. Если Компонент является session beans с поддержкой состояний, то когда будет вызван метод reserveSeats(& ), экземпляр session bean "запомнит" количество мест, и вам не нужно будет опять передавать эту информацию в метода purchase(& ). Если session beans не поддерживает состояния, Компонент не будет хранить в памяти информацию, переданную в предыдущем вызове метода, так что клиенту нужно будет передавать ее при каждом вызове метода. Существует несколько стратегий для реализации и оптимизации передачи состояний, но состояния все равно должно передаваться при каждом вызове метода.
Причина существования этих двух типов session beans достаточно проста: неотъемлемой частью некоторых бизнес-процессов является отсутствие состояний (особенно это относится к тем процессам, которые вплотную привязаны к HTTP), а для других процессов неотъемлемо наличие состояний; архитектура призвана отразить это различие.
Есть технический подтекст в использовании одного типа session bean или другого, но так же, как и в случае сравнения CMP и BMP, детальное обсуждение выходит за рамки этой главы. Одна вещь, которую вы должны запомнить, состоит в том, что session bean без состояний ведут себя лучше при работе с экземпляром механизма пулинга (объединения) Контейнера, по сравнения с session bean с поддержкой состояний. Так как экземпляр session bean без поддержки состояний не предназначен для запоминания любой информации о состоянии, передаваемой клиентом, при завершении работы метода, этот же самый экземпляр может легко быть переназначен другому клиенту для вызовов других методов. Если экземпляр session bean поддерживает состояния, Контейнер не может переназначить его другому клиенту до тех пор, пока он не переместит информацию о состояниях в какое-то временное хранилище для последующего использования (в EJB этот процесс называется активация и пассивация). В этом заключено общее непонимание того, что при объединении (pooling) экземпляров, session beans без состояний улучшают масштабируемость, но это не при любых условиях. Ваш Контейнер должен быть очень хорошо оптимизирован относительно механизма активизации и пассивации, так чтобы перемещение состояния session bean с поддержкой состояний в некоторое вторичное хранилище и извлечение из него оказывало очень малое воздействие на производительность. Во-вторых, если вы используете session bean без поддержки состояний, вы должны передать состояние клиента в session bean при каждом вызове, и если клиент и session bean находятся на двух различных распределенных уровнях, то процесс постоянной передачи состояния, а также сериализация и десериализация параметров метода, как этого требует RMI, может стать критическим местом.
Интересно замечание относительно объединения (pools) экземпляров. Дело в том, что ваш Контейнер может их вообще не понимать. Если принять во внимание недавнюю оптимизацию, введенную в компиляторы Java и JVM, современные Контейнеры могут решить, что выделение блока памяти и сборка мусора более эффективное занятие, чем управление объединением.
И наконец, третий тип Enterprise JavaBean: Message-Driven Beans (MDB). MDB работает в кооперации с системой сообщений JAVA [Java Messaging System](JMS), которая является абстрактным API для системы Message-Oriented Middleware (MOM), более-менее похожую на то, как JDBC является абстрактным API поверх SQL базы данных.
Еще раз, у нас нет места в этой главе для полного описания системы MOM. Коротко, система MOM предоставляет модель сообщений с публичной подпиской, основанной на асинхронной, распределенной очереди сообщений. MOM сообщение суть пакет информации, которое кто-то публикует, а кто-то другой интересуется им и принимает его. MOM сообщения публикуются в и извлекаются из очереди или канала. Источник сообщения и подписчик могут находиться в двух разных процессах, а сообщение посылается в MOM очередь, которая гарантирует, что оно будет доставлено, даже в случае сбоя системы. MOM система чрезвычайно полезна для реализации любой формы распределенного, асинхронного процесса - она чем-то похожа на обработку событий в самостоятельном приложении.
MBD являются приемниками MOM сообщений, приходящих через JMS API. MDB обычно реализуются для выполнения некоторых действий при получении сообщений и выступают в роли объектно-ориентированных точек соединения между подсистемами, взаимодействующих посредством JMS. Например, MDB может реализовать посылку электронной почты администратору (используя JavaMail API), когда будет получено сообщение об определенном событии.
Отличие MDB от session beans и entity beans состоит в том, что они не предоставляют никаких удаленных или локальных представлений. Другими словами, клиентский код не может получить доступ к MDB, но MDB может использовать другие EJB и другие службы.
← | Enterprise JavaBeans | EJB Роли | → |