Timer API в Enterprise Java Beans
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!
Есть вопрос? Напишите в комментариях!