Чтобы создать таймер программно, EJB необходимо получить доступ к интерфейсу javax.ejb.TimerService с использованием либо внедрения зависимостей, либо SessionContext (SessionContext.getTimerService(), см. раздел «Внедрение зависимостей» главы 7) или с помощью поиска JNDI. Как показано в табл. 8.5, API TimerService имеет несколько методов, которые позволяют создавать множество разнообразных таймеров и получать от них информацию.

Таблица 8.5. TimerService API
АннотацияОписание
createTimerСоздает таймер на основе дат, промежутков времени или продолжительности. Эти методы не используют выражения на основе календаря
createSingleActionTimerСоздает таймер одного действия, который истекает в заданный момент времени или через заданный промежуток времени. Контейнер удаляет таймер после того, как метод обратного вызова был успешно вызван
createIntervalTimerСоздает таймер на основе промежутка времени, первое его срабатывание происходит в заданный момент, а все последующие — после заданного интервала
createCalendarTimerСоздает таймер, использующий выражение на основе календаря, с помощью вспомогательного класса ScheduleExpression
getAllTimersВозвращает список всех доступных таймеров (интерфейс javax.ejb.Timer)

Вспомогательный класс ScheduleExpression позволяет создать выражения на основе календаря программно. Вы найдете методы, относящиеся к атрибутам, определенным в табл. 8.2, и сможете запрограммировать все примеры, которые видели в табл. 8.4. Ниже приведено несколько строк кода, чтобы вы имели представление об этом:

new ScheduleExpression(). dayOfMonth("Mon"). month("Jan");

new ScheduleExpression(). second("10,30,50"). minute("*/5"). hour("10–14");

new ScheduleExpression(). dayOfWeek("1,5"). timezone("Europe/Lisbon");

new ScheduleExpression(). dayOfMonth(customer.getBirthDay())

Все методы службы TimerService (createSingleActionTimer, createCalendarTimer и т. д.) возвращают объект типа javax.ejb.Timer, который содержит информацию о созданном таймере (когда он был создан, является ли постоянным и т. д.). Объект класса Timer также позволяет EJB отменить таймер до его истечения. По истечении времени контейнер вызывает соответствующий метод @javax.ejb.Timeout компонента, передавая объект класса Timer. Компонент может иметь не более одного метода, аннотированного @Timeout.

Когда CustomerEJB (см. листинг 8.4) создает новый клиент в системе (метод createCustomer()), он создает таймер по календарю на основе даты рождения заказчика. Таким образом, с каждым годом контейнер вызовет компонент для создания и отправки заказчику электронного письма, содержащего поздравление с днем рождения. Для того чтобы сделать это, компонент, не сохраняющий состояние, сначала должен внедрить ссылку на службу таймера (с помощью @Resource). Метод CreateCustomer() сохраняет клиента в базе данных и использует день и месяц рождения для создания ScheduleExpression. Календарный таймер создается и, основываясь на объектах классов ScheduleExpression и customer, использует метод TimerConfig. Метод new TimerConfig(customer, true) настраивает устойчивый таймер (что указано параметром true), который передает объект типа customer.

Листинг 8.4. Класс CustomerEJB, создающий таймер программно

@Stateless

public class CustomerEJB {

··@Resource

··TimerService t imerService;

··@PersistenceContext(unitName = "chapter08PU")

··private EntityManager em;

··public void createCustomer(Customer customer) {

····em.persist(customer);

····ScheduleExpression birthDay = new ScheduleExpression(). 

······dayOfMonth(customer.getBirthDay()). month(customer.getBirthMonth());

Перейти на страницу:

Похожие книги