Между появлением EJB 2.1 и EJB 3.0 прошло три года, что позволило экспертной группе переделать всю конструкцию. Вышедшая в 2006 году спецификация EJB 3.0 (JSR 220) порвала отношения с предыдущими версиями, поскольку была сосредоточена на легкости использования, при этом EJB-компоненты больше напоминали POJO. Компоненты-сущности EJB были заменены совершенно новой спецификацией (JPA), а сессионным EJB-компонентам больше не требовались домашние или EJB-специфичные интерфейсы компонентов. Были представлены внедрение ресурсов, перехватчики и обратные вызовы жизненного цикла.
В 2009 году спецификация EJB 3.1 (JSR 318) сопровождала Java EE 6 и шла путем предыдущих версий, даже еще больше упрощая модель программирования. Версия 3.1 привнесла удивительное количество новых функций, например представление без интерфейса, встроенные контейнеры, одиночные EJB-компоненты, TimerService с более богатыми возможностями, асинхронность, переносимые JNDI-имена и EJB Lite.
Что нового в EJB 3.2
Спецификация EJB 3.2 (JSR 345) является менее претенциозной, чем предыдущий релиз. Чтобы упростить будущее принятие этой спецификации, экспертная группа Java EE 6 составила список функций, которые могут быть ликвидированы в дальнейшем. Фактически ни одна из приведенных далее функций не была исключена из EJB 3.1, однако все они стали необязательными в версии 3.2:
• компоненты-сущности EJB 2.
• клиентское представление компонентов-сущностей EJB 2.
• EJB QL (язык запросов для CMP);
• конечные точки веб-служб на основе JAX-RPC;
• клиентское представление веб-служб JAX-RPC.
Вот почему сама спецификация состоит из двух разных документов:
•
•
Спецификация EJB 3.2 включает следующие небольшие обновления и улучшения.
• Транзакции теперь могут использоваться MBean-компонентами (ранее только EJB-компоненты могли применять транзакции; подробнее об этом мы поговорим в главе 9).
• Могут добавляться методы обратного вызова жизненного цикла EJB-компонентов с сохранением состояния, чтобы сделать их транзакционными.
• Пассивизации EJB-компонентов с сохранением состояния теперь больше нет.
• Были упрощены правила определения всех локальных/удаленных представлений EJB-компонентов.
• Было снято ограничение на получение текущего загрузчика классов, кроме того, теперь разрешено использовать пакет java.io.
• Корректировки JMS 2.0.
• Встраиваемый контейнер реализует Autocloseable, чтобы соответствовать Java SE 7.
• RMI/IIOP отсутствуют в этом релизе. Это означает, что поддержка этих технологий может быть помечена как необязательная в Java EE 8. Удаленные вызовы можно осуществлять с помощью всего лишь RMI (без интероперабельности IIOP).
В табл. 7.2 приведены основные пакеты, определенные в EJB 3.2 на сегодняшний день.
Пакет | Описание |
---|---|
javax.ejb | Классы и интерфейсы, которые определяют контракты между EJB-компонентом и его клиентами, а также между EJB-компонентом и контейнером |
javax.ejb.embeddable | Классы для Embeddable API |
javax.ejb.spi | Интерфейсы, реализуемые EJB-контейнером |
Эталонная реализация
GlassFish — это проект сервера приложений с открытым исходным кодом под руководством компании Oracle для платформы Java EE. Корпорация Sun запустила этот проект в 2005 году, и он стал эталонной реализацией Java EE 5 в 2006 году. Сегодня GlassFish версии 4 включает эталонную реализацию для EJB 3.2. Внутренне этот продукт строится вокруг модульности (исходя из времени выполнения Apache Felix OSGi), что обеспечивает очень короткое время запуска и использование различных контейнеров приложений (разумеется, Java EE 7, а также Ruby, PHP и т. д.).
На момент написания этой книги GlassFish представлял собой реализацию, совместимую только с EJB 3.2. Но скоро очередь дойдет и до остальных: OpenEJB, JBoss, Weblogic, Websphere…
Написание корпоративных EJB-компонентов
Сессионные EJB-компоненты инкапсулируют бизнес-логику и опираются на контейнер, который отвечает за организацию пула, многопоточность, безопасность и т. д. Какие артефакты нам нужны для того, чтобы создать такой мощный компонент? Один Java-класс и одна аннотация — вот и все. В листинге 7.1 показано, насколько просто контейнеру распознать, что класс является сессионным EJB-компонентом, и применить все корпоративные службы.