Статьи
YouTube-канал

Запуск задач по расписанию в Spring Boot

3 мая 2018

Тэги: Java maven Spring Spring Boot

Часто в приложениях возникает необходимость выполнять некоторые действия по расписанию, а не по запросу извне. Первое, что приходит на ум - это планировщик cron. Но если вы пишете приложение, используя Spring Boot, то можете реализовать похожий функционал, добавив всего пару аннотаций.

В качестве примера давайте создадим простой maven-проект. Затем пропишем в pom-файле Spring Boot как родителя для данного проекта:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.12.RELEASE</version>
</parent>

Также у вас должна быть секция build со стандартным содержимым:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Теперь добавим стандартный main-класс:

@EnableScheduling
@SpringBootApplication(scanBasePackages = "ru.devmark")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Аннотация @SpringBootApplication говорит о том, что это Spring Boot приложение. Параметр scanBasePackages указывает, какие пакеты (включая вложенные пакеты) сканировать для создания бинов средствами Spring.

Аннотация @EnableScheduling разрешает выполнение задач по расписанию для данного приложения. Если этой аннотации не будет, наш планировщик работать не будет.

Теперь создадим целевой сервис, в котором будет метод, выполняющий некоторую бизнес-логику. В нашем случае эту логику будем имитировать обычной задержкой через TimeUnit.SECONDS.sleep().

@Service
public class SchedulerService {

    private static final Logger log = LoggerFactory.getLogger(ProfileServiceImpl.class);

    @Scheduled(initialDelayString = "3000", fixedDelayString = "3000")
    public void doWork() throws InterruptedException {
        log.info("Start process");
        TimeUnit.SECONDS.sleep(5);
        log.info("End process");
    }
}

Аннотация @Scheduled вешается на любой метод, который нужно выполнять по фиксированному расписанию.

Параметр initialDelayString задаёт время в миллисекундах, которое пройдёт перед первым запуском данной задачи. Данный параметр бывает полезным, если после старта вашему приложению требуется время для дополнительной инициализации.

Параметр fixedDelayString задаёт время в миллисекундах между запусками данной задачи.

В нашем примере произойдёт первичная задержка в 3 секунды, затем метод будет работать 5 секунд, затем будет пауза в 3 секунды, затем будет второй запуск длиной в 5 секунд и т.д. Все задачи данного метода будут выполняться последовательно, в один поток. При этом методов с аннотацией @Scheduled может быть сколько угодно и каждый их них будет работать в своём потоке. Spring полностью берёт на себя управление этими потоками, поэтому вам больше ничего указывать не нужно.

Чтобы не хардкодить значения задержек в исходниках, а менять их через файл настроек application.properties (в командной строке путь до него задаётся через параметр --spring.config.location), можно добавить в этот файл новый параметр:

scheduler.delay=3000

Тогда аннотация @Scheduled для нашего примера примет такой вид:

@Scheduled(initialDelayString = "${scheduler.delay}", fixedDelayString = "${scheduler.delay}")

Здесь мы пользуемся другой фичой Spring, которая позволяет динамически подставлять значения параметров по их имени.


Облако тэгов

Kotlin, Java, Java 16, Java 11, Java 10, Java 9, Java 8, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Hibernate, Collections, Stream API, многопоточность, ввод-вывод, Apache, maven, gradle, JUnit, YouTube, новости, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml

Последние статьи


Комментарии

Добавить комментарий

×

devmark.ru