Бизнес-компоненты ядра в современной Java EE

Ядро Java EE -  бизнес-компонентыПростая Java, CDI и EJB — это базовые бизнес-компоненты в современном при­ложении на Java EE. Почему они называются базовыми бизнес-компонентами? Как уже отмечалось, в первую очередь мы обращаем внимание на реальные ком­мерческие задачи. Существуют компоненты и функции, нацеленные на решение основных бизнес-задач, тогда как другие просто поддерживают, делают их до­ступными или реализуют иные технические требования.


Оглавление статьи[Показать]


Java EE поставляется в комплекте с различными API, которые поддерживают десятки технических требований. Большинство из них технически обоснованы. Однако самым большим преимуществом платформы Java EE является то, что чистая бизнес-логика на Java может быть реализована с минимальным воздей­ствием технологических деталей на код. Обычно для этого достаточно CDI и EJB. Остальные API, необходимые по техническим соображениям, такие как JPA, JAX-RS, JSON-P и многие другие, вводятся по мере необходимости.

Управляемые объекты независимо от типа — CDI или EJB — реализованы в виде аннотированных классов Java, без каких-либо технических суперклас­сов или интерфейсов. Раньше это называлось представлением без интерфейса. В настоящее время этот вариант применяется по умолчанию. Расширение классов усложняет представление предметной области, не говоря уже о других недостатках, которые проявляются при тестировании. Современный фреймворк интегрируется максимально простым и незаметным способом.

 

EJB и CDI: общее и различия

Зададимся вопросом: EJB или CDI? Какие управляющие объекты применять и когда?

Вообще говоря, у EJB больше функциональных возможностей, готовых к ис­пользованию. Управляемые объекты CDI представляют собой несколько упро­щенную альтернативу. Каковы основные различия между этими технологиями и как они влияют на работу программиста?

Первое различие — это области видимости. Объекты сессии EJB либо не со­храняют состояние, то есть остаются активными в течение всего клиентского запроса, либо сохраняют состояние, то есть остаются активными в течение времени жизни HTTP-сессии клиента, либо являются синглтонами. Управ­ляемые объекты CDI имеют дополнительные возможности, такие как добав­ление нестандартных областей действия, а область видимости, выбираемая по умолчанию, является зависимой — она активна в зависимости от времени жизни ее точки внедрения. Подробнее об этом читайте в подразделе «Области видимости».

Другое различие между управляемыми объектами EJB и CDI заключается в том, что EJB-объекты неявно решают определенные сквозные задачи, такие как мониторинг, транзакции, обработка исключений и управление параллелизмом для синглтонов. Например, при вызове бизнес-метода EJB неявно запускает техническую транзакцию, которая остается активной в течение всего времени выполнения метода и объединяет источники данных или внешние системы.

Кроме того, EJB без сохранения состояния после использования объединя­ются. Это означает, что после вызова бизнес-метода для объекта без сохранения состояния сущность этого объекта может и будет применяться повторно из кон­тейнера. Благодаря этому EJB-объекты немного эффективнее, чем CDI, которые заново создаются каждый раз, когда их область видимости требует этого.

На практике технические различия не очень сильно влияют на работу про­граммиста. За исключением применения разных аннотаций, обе технологии могут использоваться в одном и том же стиле. Java EE движется к возможности предоставлять более открытый выбор из этих двух вариантов. Например, начиная с версии Java EE 8, можно обрабатывать асинхронные события исключительно с помощью CDI, а не только привлекая EJB-объекты.

Однако интеграция функциональности от CDI — одна из самых серьез­ных возможностей API Java EE. Уже только внедрение зависимостей, CDI-генераторы и события являются эффективными средствами для решения раз­личных задач.

Главная, наиболее широко применяемая функция CDI — это внедрение за­висимостей с помощью аннотации @Inject. Оно реализовано таким образом, что программисту не нужно задумываться, какая технология Java EE управляет объектами, — она просто работает. Вы можете смешивать и комбинировать CDI-объекты и EJB с любыми областями видимости — фреймворк сам поза­ботится о том, какие объекты создаются или используются в данной области видимости. Это обеспечивает гибкость, например, когда объекты с более ко­роткой областью видимости внедряются в объекты с более длинной областью видимости — допустим, когда объект с областью видимости в пределах сессии внедряется в синглтон.

Данная функция поддерживает бизнес-задачи таким образом, что контуры и элементы управления могут просто внедрять нужные зависимости, не занимаясь их созданием или управлением ими.

В следующем коде показано, как контур, реализованный в виде объекта сессии без сохранения состояния, внедряет необходимые элементы управления:

import javax.ejb.Stateless;
import javax.inject.Inject;

@Stateless
public class CarManufacturer {

   @Inject
   CarFactory carFactory;

   @Inject
   CarStorage carStorage;

   public Car manufactureCar (Specification spec) {
      Car car = carFactory.createCar (spec); carStorage.store (car);
      return car;
   }
}

Класс CarManufacturer представляет собой EJB-объект без сохранения со­стояния. Внедренные компоненты CarFactory и CarStorage реализованы в виде CDI-объектов с зависимыми областями видимости, которые будут созданы и вне­дрены в EJB-объект. Платформа Java EE упрощает устранение зависимостей, позволяя с помощью аннотации @Inject вставлять любые объекты, необходи­мые для проекта. Но так было не всегда — прежде для внедрения EJB-объектов задействовалась аннотация @EJB. Аннотация @Inject упрощает использование объектов в Java EE.

Внимательные читатели могли заметить, что внедрение через поле с областями видимости осуществляется внутри пакета Java. Внедрение через поле меньше влияет на содержимое класса, поскольку позволяет не обращаться к его кон­структору. Видимость внутри пакета дает программистам возможность создавать и внедрять зависимости в тестовой области видимости.

 

Генераторы CDI

Генераторы CDI — это еще одна функция Java EE, которая особенно полезна для реализации всевозможных фабрик. Генераторы, в основном реализуемые как методы, создают объект, который можно внедрять в другие управляемые объекты. Это отделяет логику создания и конфигурации от использования. Генераторы полезны в случаях, когда нужно вводить дополнительные типы, помимо тех, которые внедряются управляемыми объектами.

Далее показано определение метода-генератора CDI:

import javax.enterprise.inject.Produces; 

public class CarFactoryProducer {

   @Produces
   public CarFactory exposeCarFactory() {
      CarFactory factory = new BMWCarFactory();
      // дополнительная логика
      return factory;
   }
}

Открытый тип CarFactory можно ввести просто с помощью внедрения аннота­цией @Inject, как было показано ранее в примере с CarManufacturer. Каждый раз, когда нужна сущность CarFactory, CDI-объект вызывает метод exposeCarFactory() и вставляет возвращаемый объект в точку внедрения.

Этих методов достаточно для большинства случаев использования основной бизнес-логики.

 

Генерация событий предметной области

Для тех случаев, когда необходимо еще больше отделить бизнес-логику от управляемых объектов, в CDI предусмотрена функция обработки событий. Управляемые объекты могут активизировать объекты событий, которые затем действуют как полезная нагрузка и обрабатываются наблюдателями событий. Активизируя и обрабатывая события CDI, мы отделяем основную бизнес-логику от побочных аспектов обработки событий. Этот прием применяется, в частно­сти, в тех случаях, когда в бизнес-логике уже продумана концепция событий.

По умолчанию события CDI обрабатываются синхронно, прерывая выполнение в том месте, где они были активизированы. Они также могут обрабатываться асинхронно или в определенных точках жизненного цикла технической транз­акции.

На примере следующего кода показано, как определять и активизировать со­бытия CDI в бизнес-сценарии:

import javax.enterprise.event.Event;

@Stateless
public class CarManufacturer {

    @Inject
    CarFactory carFactory;

    @Inject
    Event<CarCreated> carCreated;

    public Car manufactureCar(Specification spec) {
        Car car = carFactory.createCar(spec);
        carCreated.fire(new CarCreated(spec));
        return car;
    }
}

Событие CarCreated является неизменяемым и содержит относящуюся к со­бытию предметной области информацию, такую как спецификация автомобиля. Само событие обрабатывается в классе CreatedCarListener, который находится в следующем пакете управления:

import javax.enterprise.event.Observes;

public class CreatedCarListener {

    public void onCarCreated(@Observes CarCreated event) {
        Specification spec = event.getSpecification();
        // обработка события
    }
}

Таким образом, обработчик события отделен от основной бизнес-логики. Контейнер CDI сам обеспечит подключение функций обработки событий и син­хронный вызов метода onCarCreated().

Подробнее об активизации и обработке событий асинхронно или в определен­ных точках жизненного цикла транзакции читайте в разделе «Последовательность выполнения».

События CDI — это способ отделить определение событий предметной об­ласти от их обработки. Тогда можно изменить или усилить логику обработчика событий, не затрагивая компонент manufactureCar.

 

Области видимости

Область видимости управляемых объектов очень важна в тех случаях, когда со­стояние сохраняется в приложении дольше чем на протяжении одного запроса.

Если весь бизнес-процесс можно реализовать без сохранения состояния, про­сто выполняя некоторую логику и затем отбрасывая все состояния, то определить область видимости очень легко. В большинстве случаев для этого достаточно объектов сессии без сохранения состояния и зависимых от области видимости объектов CDI.

Области видимости синглтона EJB и приложения CDI также довольно часто используются. Отдельные сущности управляемых объектов предоставляют про­стой способ хранения или кэширования информации с длительным временем жизни. Наряду со сложной технологией кэширования, синглтон, содержащий простые наборы или отображения с контролем параллелизма, по-прежнему остается простейшим способом разработки кратковременных хранилищ данных, ориентированных на решение конкретных задач. Синглтоны также обеспечивают единую точку запуска функций, доступ к которым по определенным причинам должен быть ограничен.

И последняя область видимости управляемых объектов EJB и CDI — это область сессии, привязанная к HTTP-сессии клиента. Объекты из этой области остаются активными и могут быть повторно использованы вместе со всеми своими состояниями, пока активна сессия пользователя. Однако при хранении данных сессии в объектах с сохранением состояния возникает проблема, когда клиенты заново подключаются к тому же серверу приложений.

Это, безусловно, возможно, но не позволяет создавать приложения без сохра­нения состояния, которыми было бы легко управлять. Если приложение стано­вится недоступным, то все временные данные сессии теряются. В современных корпоративных приложениях в целях оптимизации состояние обычно хранится в базе данных или кэшах. Поэтому объекты с видимостью в пределах сессии применяются все реже.

Управляемые объекты CDI имеют больше готовых областей видимости, а именно область видимости в пределах обмена данными и зависимую область видимости (используется по умолчанию). Существует также возможность соз­дания нестандартных областей видимости для особых требований. Однако опыт показывает, что встроенных областей видимости достаточно для большинства корпоративных приложений. Подробная информация о том, как расширить плат­форму и разработать дополнительные области видимости, содержится в специ­фикации CDI.

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

 

Вас заинтересует / Intresting for you:

Распространенные заблуждения о...
Распространенные заблуждения о... 1646 просмотров Ирина Светлова Thu, 21 Jun 2018, 18:35:12
Выбор среды для разработки код...
Выбор среды для разработки код... 1611 просмотров Stas Belkov Sun, 10 Jun 2018, 14:21:35
Вызов Java-программ из PL/SQL:...
Вызов Java-программ из PL/SQL:... 3382 просмотров Antoni Mon, 06 Jan 2020, 15:02:03
Как выполнить / скомпилировать...
Как выполнить / скомпилировать... 3216 просмотров Stas Belkov Thu, 21 Jun 2018, 18:32:00
Войдите чтобы комментировать

ildergun аватар
ildergun ответил в теме #9349 19 фев 2019 09:36
Интересные и важные концепции программирования на Java. Спасибо за материал!