Planowanie zadań cyklicznych w Spring Boot


Planowanie zadań cyklicznych w Spring Boot

Zadania cykliczne to zadania które odbywają się co określony interwał czasowy. Przykładem może być skrypt który cyklicznie czyści katalog z logami po określonym czasie ze względu na jego duży rozmiar na dysku. W Spring Boot zadania cykliczne tworzymy z użyciem dwóch adnotacji:

  • @EnableScheduling,
  • @Scheduler.

Adnotacja @EnableScheduling używana jest w klasie konfiguracyjnej:

@SpringBootApplication
@EnableScheduling
public class SchedulerApplication {
	public static void main(String[] args) {
		SpringApplication.run(SchedulerApplication.class, args);
	}
}

Adnotacja @Scheduler używana jest do wskazania która metoda ma się cyklicznie wykonywać i w jakim odstępie czasowym. Przykładem jest metoda która wyświetla na konsoli komunikat o aktualnie wykonywanym zadaniu:

@Component
public class ScheduledTaskLogger {

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

    @Scheduled(fixedRate = 1000, zone ="Europe/Warsaw")
    public void executeTask() {

        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
        log.info("Task executed at {}", now);
    }
}

Adnotacja @Scheduler przyjmuje następujące parametry:

  • cron uruchamia zadanie według zadanego wzorca:

sekundy, minuty, godziny, dni miesiąca, miesiące oraz dni tygodnia.

  • zonestrefa czasowa według której ma zostać uruchomiony zadanie crona,
  • fixedDelay, fixedDelayStringinterwał określający co jaki czas ma zostać uruchomione zadanie,
  • fixedRate, fixedRateString interwał określający po jakim czasie ma zostać wywołana metoda kolejny raz,
  • initialDelay, initialDelayStringopóźnienie z jakim pierwszy raz ma się wywołać dana metoda.

Istnieje również możliwość połączenia zadań tworząc swego rodzaju harmonogram za pomocą adnotacji @Schedules:

@Schedules({
        @Scheduled(cron = "15 * * * * *"),
        @Scheduled(fixedDelay = 5000)
})
public void executeTask2() {
    String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
    log.info("Task 2 executed at {}", now);
}

Jest również możliwość zmiany parametrów w trybie runtime (przez pół minuty zadanie wykonywane jest bez zmian natomiast po połowie minuty zadanie wykonywane jest co sekundę).

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {

    @Bean
    public ScheduledTaskLogger SchedulerTaskLogger() {
        return new ScheduledTaskLogger();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        final LocalDateTime dateChange = LocalDateTime.now().plusSeconds(30);
        taskRegistrar.addFixedRateTask(() -> {
            if (LocalDateTime.now().isAfter(dateChange)) {
                SchedulerTaskLogger().executeTask2();
            }
        }, 1000);
    }
}


Leave a comment

Your email address will not be published.


*