Выполнение кода по расписанию в Spring Framework

    Тут приспичило мне периодически запускать некоторый код в небольшом проектике написанном на Spring Framework. Я уж было приготовился по старой памяти (еще со спринга 2.x) к долгому прикручиванию quartz-а и написании кучи конфигов на xml, как оказалось все значительно проще

    Документация Spring Framework как обычно дает исчерпывающий, но иногда избыточный ответ

    На самом деле все просто:

    1. Делай раз — добавь в свой спринговый конфиг (минимальный все-таки в любом проекте присутсвует — не все еще делается аннотациями) task namespace, что бы выглядело примерно так (обратите внимание на слово task):
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
    www.springframework.org/schema/beans www.springframework.org/schema/beans/spring-beans.xsd
    www.springframework.org/schema/context www.springframework.org/schema/context/spring-context.xsd
    www.springframework.org/schema/tx www.springframework.org/schema/tx/spring-tx.xsd
    www.springframework.org/schema/task www.springframework.org/schema/task/spring-task.xsd">


    2. Делай два — там же сконфигури шедулер:

    <task:annotation-driven executor="executor" scheduler="scheduler"/>
    <task:executor id="executor" pool-size="5"/>
    <task:scheduler id="scheduler" pool-size="10"/>


    3. Делай три — повесь на метод какого-нибудь бина аннотацию @Scheduled, например:
    @Scheduled(fixedDelay=5000)
    public void doSomething() {
    // do something every 5 seconds
    }

    Все! В очередной раз убедился в своей любви к спрингу — когда технологии разрабатывается не ради технологий, а ради удобства разработчиков
    Поделиться публикацией

    Комментарии 16

      +5
      еще можно сделать так:
      @Scheduled(cron = "* * * * * *")
        0
        Прошивать расписание в код в большинстве случаев не есть правильно. Потому работаю по-старинке.
        0
        Я уж было приготовился по старой памяти (еще со спринга 2.x) к долгому прикручиванию quartz-а и написании кучи конфигов на xml, как оказалось все значительно проще

        Я как раз на днях вспоминал о quartz-е, так как и мне нужно настроить выполнение некого кода по расписанию. А оказывается, можно сделать так. Спасибо!
          0
          А вот интересно — сконфигурил я такой аннотацией запуск чего-либо раз в 5 секунд, а потом обнаружил, что это слишком часто/редко. Можно переконфигурить настройки для этого места снаружи?
            0
            нет
              0
              обидно, на самом деле. Потому что когда в продакшене обнаруживается проблема с настройками планировщика, перекомпилировать и обновлять сервер никто не позволит.
                0
                используйте xml конфигурацию, в чем проблема то
              +1
              Ну в более сложном случае и конфигурация будет сложней — вам надо будет задать свой Trigger, сконфигурировать его из properties-файла и потом дергать задачи используя этот триггер
              В этому случае как раз придется писать много xml — и аннотацией не получится воспользоваться

              Все подробно написано в спринговой доке — я тут намеренно привел простейний пример
              0
              В Play Framework тоже делается довольно просто:

              import play.jobs.*;

              /** Fire at 12pm (noon) every day **/
              @On("0 0 12 * * ?")
              public class Bootstrap extends Job {

              public void doJob() {
              Logger.info("Maintenance job ...");
              ...
              }

              }
                –1
                Есть ещё прекрасная аннотация Every:

                @Every(«5min»)
                public class Bootstrap extends Job {

                }
                  –2
                  И я бы сказал, что не «В Play Framework тоже делается довольно просто», а «В Play Framework тоже делается ещё проще», потому что нет никаких конфигурационных xml-файлов.
                    +1
                    Отсутствие конфигурационных файлов — это на самом деле недостаток, а не достоинство.

                    Потому что когда в продакшене обнаруживается проблема с настройками планировщика, перекомпилировать и обновлять сервер никто не позволит.
                      0
                      Должно быть так — аннотациями настраиваешь все из кода, чтобы проще и быстрее было программить; но если надо, нужно иметь возможность переопределить настройки для каких-то задач из файла конфигурации (и лучше всего без перезапуска сервера).
                        0
                        Править xml и перезапускать тоже может быть не очень. Тут нужно смотреть на что-то настраиваемое через JMX или конфиг в БД.
                    0
                    Активно пользуюсь аннотацией @Scheduled. Из недостатков можно отметить невозможность отключения крона (только указав день/месяц/деньНедели максимально отдалённый от текущей даты) и невозможность указания имени треда.
                      +1
                      Scheduled понравился больше чем кварц. по-моему он по легче и по стабильнее.
                      Из интересных моментов хочу добавить:

                      если внутри метода doSomething происходит исключение, любое, то весь Scheduled отвалится и не следующее событие по расписанию не произойдет.
                      После перезапуска приложения — всё норм…

                      Так что коллеги, если используете Scheduled, не забывайте ваш код оформлять в try-catch

                      В том же кварце таких глюков не обнаружено. Но с ним тоже были определенные мучения.
                      Например, задать запуск — каждое воскресение. обязательно напротив дня месяца нужно ставить ?, а не *. Иначе он вообще не запустится

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое