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

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

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

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

>··}

>··public synchronized 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;

>··}

>}

Время ожидания конкурентного доступа и запрет конкурентного доступа

Попытка конкурентного доступа, при которой не может быть незамедлительно применена соответствующая блокировка, будет блокироваться до тех пор, пока не получится продвинуться вперед. Аннотация @AccessTimeout используется для определения периода, на протяжении которого должна блокироваться попытка доступа, прежде чем истечет время ожидания. Значение @AccessTimeout, равное -1, показывает, что клиентский запрос будет блокироваться неопределенно долго до тех пор, пока не получится продвинуться вперед. Значение @AccessTimeout, равное 0, говорит о том, что конкурентный доступ запрещен. В результате будет сгенерировано исключение ConcurrentAccessException, если клиент вызовет метод, используемый в текущий момент. Это может сказаться на производительности, поскольку клиентам, возможно, придется обработать исключение, снова попытаться получить доступ к EJB-компоненту, после чего вероятны генерирование еще одного исключения, новая попытка и т. д. В листинге 7.13 CacheEJB запрещает конкурентный доступ к методу addToCache(). Это означает, что если клиент А будет добавлять объект в кэш, а клиент В захочет сделать то же самое одновременно с ним, то для клиента В будет сгенерировано исключение и ему придется попытаться снова позднее (либо поступить с исключением по-другому).


Листинг 7.13. Одиночный сессионный EJB-компонент, запрещающий конкурентный доступ к методу

>@Singleton

>public class CacheEJB {

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

>··@AccessTimeout(0)

>··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);

>··}

>··@Lock(LockType.READ)

>··public Object getFromCache(Long id) {

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

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

>····else

>······return null;

>··}

>}

Внедрение зависимостей

Я уже говорил о внедрении зависимостей ранее, и вы столкнетесь с этим механизмом несколько раз в последующих главах. Это простой, но все же мощный механизм, используемый Java EE 7 для внедрения ссылок на ресурсы в атрибуты. Вместо того чтобы приложению искать ресурсы с использованием JNDI, контейнер сам внедряет их. Внедрение осуществляется во время развертывания. Если есть вероятность того, что данные не будут использоваться, EJB-компонент может избежать затрат, связанных с внедрением ресурсов, выполнив JNDI-поиск. JNDI является альтернативой внедрению. При использовании JNDI код выталкивает данные из стека, только если они необходимы, вместо того чтобы принимать подвергнутые проталкиванию в стек данные, которые могут вообще не потребоваться.

Контейнеры могут внедрять ресурсы различных типов в сессионные EJB-компоненты с помощью разных аннотаций (или дескрипторов развертывания):

• @EJB — внедряет ссылку на локальное представление, удаленное представление и представление без интерфейса EJB-компонента в аннотированную переменную;

• @PersistenceContext и @PersistenceUnit — выражают зависимость от EntityManager и EntityManagerFactory соответственно (см. подраздел «Получение менеджера сущностей» раздела «Менеджер сущностей» главы 6);

• @WebServiceRef — внедряет ссылку на веб-службу;

• @Resource — внедряет ряд ресурсов, например источники данных JDBC, SessionContext, пользовательские транзакции, фабрики подключений и пункты назначения JMS, записи окружения, TimerService и т. д.;

• @Inject — внедряет почти все с использованием @Inject и @Produces, как было объяснено в главе 2.

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


Листинг 7.14. EJB-компонент без сохранения состояния, для которого используется внедрение

>@Stateless

>public class ItemEJB {

>··@PersistenceContext(unitName = "chapter07PU")

>··private EntityManager em;

>··@EJB

>··private CustomerEJB customerEJB;

>··@Inject

>··private NumberGenerator generator;

>··@WebServiceRef

>··private ArtistWebService artistWebService;

>··private SessionContext ctx;

>··@Resource

>··public void setCtx(SessionContext ctx) {

>····this.ctx = ctx;

>··}

>··//…

>}

API-интерфейс SessionContext

Сессионные EJB-компоненты являются бизнес-компонентами, располагающимися в контейнере. Обычно они не обращаются к контейнеру и не используют контейнерные службы напрямую (управление транзакциями, безопасность, внедрение зависимостей и т. д.). Предусматривается, что контейнер будет прозрачно взаимодействовать с этими службами от имени EJB-компонента (это называется инверсией управления). Однако иногда EJB-компоненту требуется явно использовать контейнерные службы в коде (например, чтобы пометить транзакцию как подлежащую откату). Это можно сделать с помощью интерфейса javax.ejb.SessionContext. API SessionContext разрешает программный доступ к контексту времени выполнения, который обеспечивается для экземпляра сессионного EJB-компонента. Он расширяет интерфейс javax.ejb.EJBContext. В табл. 7.3 приведено описание некоторых методов API-интерфейса SessionContext.


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