Изучаем Java EE 7 - [15]

Шрифт
Интервал

Java EE была создана в конце 1990-х годов, и в самой первой версии уже присутствовали компоненты EJB, сервлеты и служба JMS. Эти компоненты могли использовать JNDI для поиска ресурсов, управляемых контейнером, таких как интерфейс JDBC DataSource, JMS-фабрики либо адреса назначения. Это сделало возможной зависимость компонентов и позволило EJB-контейнеру взять на себя сложности управления жизненным циклом ресурса (инстанцирование, инициализацию, упорядочение и предоставление клиентам ссылок на ресурсы по мере необходимости). Однако вернемся к теме внедрения ресурса, выполняемого контейнером.

В платформе Java EE 5 появилось внедрение ресурсов для разработчиков. Это позволило им внедрять такие ресурсы контейнера, как компоненты EJB, менеджер сущностей, источники данных, фабрики JMS и адреса назначения, в набор определенных компонентов (сервлетов, связующих компонентов JSF и EJB). С этой целью Java EE 5 предоставила новый набор аннотаций (@Resource, @PersistenceContext, @PersistenceUnit, @EJB и @WebServiceRef).

Новшеств Java EE 5 оказалось недостаточно, и тогда Java EE 6 создала еще две спецификации для добавления в платформу настоящего внедрения зависимостей (DI): Dependency Injection (запрос JSR 330) и Contexts and Dependency Injection (запрос JSR 299). На сегодняшний день в Java EE 7 внедрение зависимостей используется еще шире: для связи спецификаций.

Управление жизненным циклом

Жизненный цикл POJO достаточно прост: вы, Java-разработчик, создаете экземпляр класса, используя ключевое слово new, и ждете, пока сборщик мусора (Garbage Collector) избавится от него и освободит некоторое количество памяти. Но если вы хотите запустить компонент CDI внутри контейнера, вам нельзя указывать ключевое слово new. Вместо этого вам необходимо внедрить компонент, а все остальное сделает контейнер. Тут подразумевается, что только контейнер отвечает за управление жизненным циклом компонента: сначала он создает экземпляр, затем избавляется от него. Итак, как же вам инициализировать компонент, если вы не можете вызвать конструктор? В этом случае контейнер дает вам указатель после конструкции экземпляра и перед его уничтожением.

Рисунок 2.1 показывает жизненный цикл управляемого компонента (следовательно, и компонента CDI). Когда вы внедряете компонент, только контейнер (EJB, CDI или веб-контейнер) отвечает за создание экземпляра (с использованием кодового слова new). Затем он разрешает зависимости и вызывает любой метод с аннотацией @PostConstruct до первого вызова бизнес-метода на компоненте. После этого оповещение с помощью обратного вызова @PreDestroy сигнализирует о том, что экземпляр удаляется контейнером.


Рис. 2.1. Жизненный цикл управляемого компонента


В следующих главах вы увидите, что большинство компонентов Java EE следуют жизненному циклу, описанному на рис. 2.1.

Области видимости и контекст

Компоненты CDI могут сохранять свое состояние и являются контекстуальными. Это означает, что они живут в пределах четко определенной области видимости. В CDI такие области видимости предопределены в пределах запроса, сеанса, приложения и диалога. Например, контекст сеанса и его компоненты существуют в течение жизни сеанса HTTP. В течение этого времени внедренные ссылки на компоненты также оповещены о контексте. Таким образом, целая цепочка зависимостей компонентов является контекстуальной. Контейнер автоматически управляет всеми компонентами в пределах области видимости, а в конце сессии автоматически уничтожает их.

В отличие от компонентов, не сохраняющих состояние (например, сеансовых объектов без сохранения состояния), или синглтонов (сервлетов), различные клиенты компонента, сохраняющего состояние, видят этот компонент в разных состояниях. Когда компонент сохраняет свое состояние (ограничен сессией, приложением и диалогом), имеет значение, какой экземпляр компонента находится у клиента. Клиенты (например, другие компоненты), выполняющиеся в том же контексте, будут видеть тот же экземпляр компонента. Но клиенты в другом контексте могут видеть другой экземпляр (в зависимости от отношений между контекстами). Во всех случаях клиент не управляет жизненным циклом экземпляра исключительно путем его создания и уничтожения. Это делает контейнер в соответствии с областью видимости.

Перехват

Методы-перехватчики используются для вставки между вызовами бизнес-методов. Это похоже на аспектно-ориентированное программирование (АОП). АОП — это парадигма программирования, отделяющая задачи сквозной функциональности (влияющие на приложение) от вашего бизнес-кода. Большинство приложений имеют общий код, который повторяется среди компонентов. Это могут быть технические задачи (сделать запись в журнале и выйти из любого метода, сделать запись в журнале о длительности вызова метода, сохранить статистику использования метода и т. д.) или бизнес-логика. К последней относятся: выполнение дополнительных проверок, если покупатель приобретает товар более чем на $10 000, отправка запросов о повторном заполнении заказа, если товара недостаточно в наличии, и т. д. Эти задачи могут применяться автоматически посредством AOP ко всему вашему приложению либо к его подсистеме.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

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