Timer API в Enterprise Java Beans
2026-03-10 21:14 Diff

Теги: java, @postconstruct, enterprise java beans, timer api, @timeout, timerservice, @resource, createtimer(), programmatictimout, getinfo, @schedule, @schedules, dotimerwork, workerbean, java enterprise

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!

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