Несколько дней новогоднего волшебства:
Успейте начать обучение в 2018-ом году со скидкой до 30%!
Выбрать курс

Timer API в Enterprise Java Beans

JavaEE_Deep_17.08_Site.png

Timer API — полезный инструмент Enterprise Java Beans, позволяющий легко создавать задачи, выполняющиеся с задержкой по времени или требующие выполнения по расписанию. Например, можно в строго определённый час запускать формирование ежедневных отчётов, собирая сводную статистику. Для работы на выбор разработчику предоставляются два типа таймеров.

Программный

Программные таймеры инжектируются в самом бине и используют аннотацию @Timeout, которой следует пометить метод, требующий выполнения по расписанию. Чтобы определить сам таймер, код его инициализации рекомендуется выносить в отдельный метод, который обычно помечается аннотацией @PostConstruct.

Рассмотрим фрагмент кода для создания программного таймера, который будет запускать бизнес-метод, срабатывая каждую секунду:

@Startup
@Singleton
public class ProgrammaticAtFixedRateTimerBean {

    @Inject
    Event<TimerEvent> event;

    @Resource
    TimerService timerService;

    @PostConstruct
    public void initialize() {
        timerService.createTimer(0,1000, "Every second timer with no delay");
    }

    @Timeout
    public void programmaticTimout(Timer timer) {
        event.fire(new TimerEvent(timer.getInfo().toString()));
    }
}

Программные таймеры EJB создаются с помощью службы TimerService, которую легко заинжектить в приложение, используя аннотацию @Resource, а уже создание нужного таймера осуществляется вызовом метода createTimer() у данного сервиса.

Первым параметром этого метода мы определяем время задержки срабатывания таймера (или 0, если метод важно запустить сразу). Вторым аргументом определяется периодичность повторений (оба параметра указываются в миллисекундах). Далее требуемый метод programmaticTimout помечается аннотацией @Timeout, а в качестве параметра метода используется программный таймер, из которого мы получаем информацию о нем вызовом метода getInfo.

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

Автоматический

Также спецификация EJB предусматривает встроенные средства для создания автоматических таймеров, которые позволяют решать ту же задачу, используя аннотации @Schedule и @Schedules. При таком подходе сам контейнер будет заботиться об отложенном запуске и повторных вызовах этих методов без необходимости написания кода инициализации таймера.

Рассмотрим работу автоматических таймеров на примере следующего кода:

@Singleton
public class FixedTimerBean {

    @EJB
    private WorkerBean workerBean;

    @Lock(LockType.READ)
    @Schedule(second = "*/5", minute = "*", hour = "*")
    public void atSchedule() throws InterruptedException {
        workerBean.doTimerWork();
    }
}

Согласно данному листингу, каждые 5 секунд будет выполняться метод doTimerWork у объекта workerBean. В данном случае метод бина будет вызываться встроенным автоматическим таймером.

В нижеследующем коде демонстрируется пример автоматического таймера, в котором используются разные события для повторного запуска, объединённые аннотацией @Schedules :

@Schedules ({
   @Schedule(dayOfMonth="Last"),
   @Schedule(dayOfWeek="Fri", hour="23")
})
public void doPeriodicCleanup() { ... }

Остаётся добавить, что Timer API — это проверенный способ, позволяющий разработчику запускать задачи на выполнение по расписанию без необходимости писать собственные «велосипеды».

Если хотите узнать о нём больше, записывайтесь на курс «Разработчик Java Enterprise» от OTUS!

Есть вопрос? Напишите в комментариях!

Автор
0 комментариев
Для комментирования необходимо авторизоваться