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

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


Рис. 7.6. Клиенты, осуществляющие доступ к одиночному EJB-компоненту


Примечание

Одиночные EJB-компоненты не поддерживают кластер. Кластер — это группа контейнеров, которые тесно работают друг с другом (совместно используют одни и те же ресурсы, EJB-компоненты и т. д.). Таким образом, в ситуациях, когда несколько распределенных контейнеров будут образовывать кластер, функционируя на нескольких машинах, каждый контейнер будет располагать своим экземпляром одиночного EJB-компонента.


Чтобы превратить приведенный в листинге 7.9 код одиночного Java-класса в код одиночного сессионного EJB-компонента (листинг 7.10), не потребуется много усилий. Фактически вам придется лишь снабдить класс аннотацией @Singleton, при этом не придется беспокоиться о закрытом конструкторе или статическом методе getInstance(). Контейнер убедится в том, что вы создали только один экземпляр. Аннотация @javax.ejb.Singleton обладает тем же самым API-интерфейсом, что и аннотация @Stateless, описанная ранее в листинге 7.7.


Листинг 7.10. Одиночный сессионный EJB-компонент

>@Singleton

>public class CacheEJB {

>··private Map cache = new HashMap<>();

>··public void addToCache(Long id, Object object) {

>····if (!cache.containsKey(id))

>······cache.put(id, object);

>··}

>··public void removeFromCache(Long id) {

>····if (cache.containsKey(id))

>······cache.remove(id);

>··}

>··public Object getFromCache(Long id) {

>····if (cache.containsKey(id))

>······return cache.get(id);

>····else

>······return null;

>··}

>}

Как вы можете видеть, разработка сессионных EJB-компонентов без сохранения состояния, с сохранением состояния и одиночных очень легка: вам потребуется лишь одна аннотация. Вместе с тем об одиночных EJB-компонентах можно сказать еще немного. Можно инициализировать их при запуске, объединять в цепочку и настраивать их конкурентный доступ.

Инициализация при запуске

Когда клиентскому классу требуется доступ к методу в одиночном сессионном EJB-компоненте, контейнер обеспечивает либо создание его экземпляра, либо использование того, что уже имеется в этом контейнере. Однако инициализация одиночного EJB-компонента иногда может отнимать много времени. Представим, что CacheEJB (приведенному в листинге 7.10) необходим доступ к базе данных для загрузки в свой кэш тысяч объектов. Первый вызов EJB-компонента окажется затратным, и первому клиенту придется ожидать завершения инициализации.

Чтобы избежать такой задержки, вы можете дать указание контейнеру инициализировать одиночный EJB-компонент при запуске. Если снабдить класс EJB-компонента аннотацией @Startup, то контейнер инициализирует его во время запуска приложения, а не в тот момент, когда клиент вызовет его. В приведенном далее коде показано, как следует использовать эту аннотацию:

>@Singleton

>@Startup

>public class CacheEJB {…}


Примечание

В Java EE 7 экспертная группа попыталась изъять аннотацию @Startup из спецификации EJB, чтобы она могла быть использована с любым управляемым MBean-компонентом или сервлетом. Сделать это не получилось, однако теоретически это окажется возможным в Java EE 8.

Объединение одиночных EJB-компонентов в цепочку

В некоторых случаях, когда у вас есть несколько одиночных EJB-компонентов, может быть важно явно задать порядок инициализации. Представим, что CacheEJB необходимо сохранить данные, которые исходят от другого одиночного EJB-компонента (скажем, CountryCodeEJB, который возвращает ISO-коды стран). Тогда CountryCodeEJB потребуется инициализировать раньше CacheEJB. Между несколькими одиночными EJB-компонентами могут существовать зависимости, которые выражаются аннотацией @javax.ejb.DependsOn. Использование этой аннотации демонстрируется в приведенном далее примере:

>@Singleton

>public class CountryCodeEJB {…}


>@DependsOn("CountryCodeEJB")

>@Singleton

>public class CacheEJB {…}

@DependsOn содержит одну или несколько строк, каждая из которых определяет имя целевого одиночного EJB-компонента. В приведенном далее коде показано, как CacheEJB зависит от инициализации CountryCodeEJB и ZipCodeEJB. @DependsOn("CountryCodeEJB", "ZipCodeEJB") дает указание контейнеру позаботиться о том, чтобы CountryCodeEJB и ZipCodeEJB были инициализированы раньше CacheEJB.

>@Singleton

>public class CountryCodeEJB {…}


>@Singleton

>public class ZipCodeEJB {…}

>@DependsOn("CountryCodeEJB", "ZipCodeEJB")

>@Startup

>@Singleton

>public class CacheEJB {…}

Как видно в этом коде, вы даже можете комбинировать зависимости, когда речь идет об инициализации при запуске. CacheEJB быстро инициализируется при запуске (поскольку снабжен аннотацией @Startup), и, следовательно, CountryCodeEJB и ZipCodeEJB тоже будут инициализированы при запуске, но раньше CacheEJB.

Вы также можете использовать полностью уточненные имена для ссылки на одиночный EJB-объект, упакованный в другой модуль в рамках одного и того же приложения. Допустим, оба CacheEJB и CountryCodeEJB упакованы в рамках одного приложения (в один и тот же файл с расширением. ear), но в разные файлы с расширением. jar (technical.jar и business.jar соответственно). В приведенном далее коде показано, как CacheEJB зависел бы от CountryCodeEJB:


Рекомендуем почитать
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 так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.