0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: java, @postconstruct, enterprise java beans, timer api, @timeout, timerservice, @resource, createtimer(), programmatictimout, getinfo, @schedule, @schedules, dotimerwork, workerbean, java enterprise</p>
1
<p>Теги: java, @postconstruct, enterprise java beans, timer api, @timeout, timerservice, @resource, createtimer(), programmatictimout, getinfo, @schedule, @schedules, dotimerwork, workerbean, java enterprise</p>
2
<p><strong>Timer API</strong>- полезный инструмент<strong>Enterprise Java Beans</strong>, позволяющий легко создавать задачи, выполняющиеся с задержкой по времени или требующие выполнения по расписанию. Например, можно в строго определённый час запускать формирование ежедневных отчётов, собирая сводную статистику. Для работы на выбор разработчику предоставляются два типа таймеров.</p>
2
<p><strong>Timer API</strong>- полезный инструмент<strong>Enterprise Java Beans</strong>, позволяющий легко создавать задачи, выполняющиеся с задержкой по времени или требующие выполнения по расписанию. Например, можно в строго определённый час запускать формирование ежедневных отчётов, собирая сводную статистику. Для работы на выбор разработчику предоставляются два типа таймеров.</p>
3
<h2>Программный</h2>
3
<h2>Программный</h2>
4
<p>Программные таймеры инжектируются в самом бине и используют аннотацию<strong>@Timeout</strong>, которой следует пометить метод, требующий выполнения по расписанию. Чтобы определить сам таймер, код его инициализации рекомендуется выносить в отдельный метод, который обычно помечается аннотацией<strong>@PostConstruct</strong>.</p>
4
<p>Программные таймеры инжектируются в самом бине и используют аннотацию<strong>@Timeout</strong>, которой следует пометить метод, требующий выполнения по расписанию. Чтобы определить сам таймер, код его инициализации рекомендуется выносить в отдельный метод, который обычно помечается аннотацией<strong>@PostConstruct</strong>.</p>
5
<p>Рассмотрим фрагмент кода для создания программного таймера, который будет запускать бизнес-метод, срабатывая каждую секунду:</p>
5
<p>Рассмотрим фрагмент кода для создания программного таймера, который будет запускать бизнес-метод, срабатывая каждую секунду:</p>
6
@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())); } }<p>Программные таймеры<strong>EJB</strong>создаются с помощью службы<strong>TimerService</strong>, которую легко заинжектить в приложение, используя аннотацию<strong>@Resource</strong>, а уже создание нужного таймера осуществляется вызовом метода<strong>createTimer()</strong>у данного сервиса.</p>
6
@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())); } }<p>Программные таймеры<strong>EJB</strong>создаются с помощью службы<strong>TimerService</strong>, которую легко заинжектить в приложение, используя аннотацию<strong>@Resource</strong>, а уже создание нужного таймера осуществляется вызовом метода<strong>createTimer()</strong>у данного сервиса.</p>
7
<p>Первым параметром этого метода мы определяем время задержки срабатывания таймера (или 0, если метод важно запустить сразу). Вторым аргументом определяется периодичность повторений (оба параметра указываются в миллисекундах). Далее требуемый метод<strong>programmaticTimout</strong>помечается аннотацией<strong>@Timeout</strong>, а в качестве параметра метода используется программный таймер, из которого мы получаем информацию о нем вызовом метода<strong>getInfo</strong>.</p>
7
<p>Первым параметром этого метода мы определяем время задержки срабатывания таймера (или 0, если метод важно запустить сразу). Вторым аргументом определяется периодичность повторений (оба параметра указываются в миллисекундах). Далее требуемый метод<strong>programmaticTimout</strong>помечается аннотацией<strong>@Timeout</strong>, а в качестве параметра метода используется программный таймер, из которого мы получаем информацию о нем вызовом метода<strong>getInfo</strong>.</p>
8
<p>Обращаю внимание, что в случае необходимости вызова таймера с задержкой при инициализации следует установить не нулевое значение в качестве первого параметра, как показано в примере, а любое другое.</p>
8
<p>Обращаю внимание, что в случае необходимости вызова таймера с задержкой при инициализации следует установить не нулевое значение в качестве первого параметра, как показано в примере, а любое другое.</p>
9
<h2>Автоматический</h2>
9
<h2>Автоматический</h2>
10
<p>Также спецификация<strong>EJB</strong>предусматривает встроенные средства для создания автоматических таймеров, которые позволяют решать ту же задачу, используя аннотации<strong>@Schedule</strong>и<strong>@Schedules</strong>. При таком подходе сам контейнер будет заботиться об отложенном запуске и повторных вызовах этих методов без необходимости написания кода инициализации таймера.</p>
10
<p>Также спецификация<strong>EJB</strong>предусматривает встроенные средства для создания автоматических таймеров, которые позволяют решать ту же задачу, используя аннотации<strong>@Schedule</strong>и<strong>@Schedules</strong>. При таком подходе сам контейнер будет заботиться об отложенном запуске и повторных вызовах этих методов без необходимости написания кода инициализации таймера.</p>
11
<p>Рассмотрим работу автоматических таймеров на примере следующего кода:</p>
11
<p>Рассмотрим работу автоматических таймеров на примере следующего кода:</p>
12
@Singleton public class FixedTimerBean { @EJB private WorkerBean workerBean; @Lock(LockType.READ) @Schedule(second = "*/5", minute = "*", hour = "*") public void atSchedule() throws InterruptedException { workerBean.doTimerWork(); } }<p>Согласно данному листингу, каждые 5 секунд будет выполняться метод<strong>doTimerWork</strong>у объекта<strong>workerBean</strong>. В данном случае метод бина будет вызываться встроенным автоматическим таймером.</p>
12
@Singleton public class FixedTimerBean { @EJB private WorkerBean workerBean; @Lock(LockType.READ) @Schedule(second = "*/5", minute = "*", hour = "*") public void atSchedule() throws InterruptedException { workerBean.doTimerWork(); } }<p>Согласно данному листингу, каждые 5 секунд будет выполняться метод<strong>doTimerWork</strong>у объекта<strong>workerBean</strong>. В данном случае метод бина будет вызываться встроенным автоматическим таймером.</p>
13
<p>В нижеследующем коде демонстрируется пример автоматического таймера, в котором используются разные события для повторного запуска, объединённые аннотацией @Schedules :</p>
13
<p>В нижеследующем коде демонстрируется пример автоматического таймера, в котором используются разные события для повторного запуска, объединённые аннотацией @Schedules :</p>
14
@Schedules ({ @Schedule(dayOfMonth="Last"), @Schedule(dayOfWeek="Fri", hour="23") }) public void doPeriodicCleanup() { ... }<p>Остаётся добавить, что<strong>Timer API</strong>- это проверенный способ, позволяющий разработчику запускать задачи на выполнение по расписанию без необходимости писать собственные "велосипеды".</p>
14
@Schedules ({ @Schedule(dayOfMonth="Last"), @Schedule(dayOfWeek="Fri", hour="23") }) public void doPeriodicCleanup() { ... }<p>Остаётся добавить, что<strong>Timer API</strong>- это проверенный способ, позволяющий разработчику запускать задачи на выполнение по расписанию без необходимости писать собственные "велосипеды".</p>
15
<p>Если хотите узнать о нём больше, записывайтесь на курс<a>"Разработчик Java Enterprise"</a>от OTUS!</p>
15
<p>Если хотите узнать о нём больше, записывайтесь на курс<a>"Разработчик Java Enterprise"</a>от OTUS!</p>
16
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
16
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
17
17