
W tym wpisie chciałam przedstawić proces tworzenia planowanych zadań. W Spring Boocie jest to wyjątkowo proste. Nie musimy tworzyć żadnych plików konfiguracyjnych. Wszystko opiera się na dwóch adnotacjach. Przekonajcie się sami.
W pom.xml potrzebujemy tylko i wyłącznie podstawowej zależności startera spring boot’owego.
Nasza klasa główna musi mieć adnotację @EnableScheduling
@SpringBootApplication
@EnableScheduling
public class SchedulerApplication {
public static void main(String[] args) {
SpringApplication.run(new Object[] { SchedulerApplication.class }, args);
}
}
Teraz przejdźmy do naszej klasy z zadaniami, które mają się wykonywać co określony interwał czasowy. Nad klasą dodajemy adnotację @Component, a nad metodą, która ma być wywoływana dodajemy @Scheduled z odpowiednim parametrem (dostępne parametry opisane poniżej).
@Component
public class ScheduledTask {
private static final Logger log = LoggerFactory.getLogger(ScheduledTask.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat(“HH:mm:ss”);
@Scheduled(fixedRate = 5000)
public void executeTask() {
log.info("Task executed at {}", dateFormat.format(new Date()));
}
}
Po uruchomieniu naszej aplikacji co 5 sekund w konsoli wyświetlany będzie komunikat z metody executeTask() 
Parametry atrybutu @Scheduled:
1. cron = “0 0 0 * * *“ Parametr ten jest CRON’owym wyrażeniem składającym się z sześciu pól reprezentujących kolejno: sekundy, minuty, godziny, dni miesiąca, miesiące oraz dni tygodnia. Oddzielone są one spacjami. Miesiące i dni tygodnia mogą być podawane jako trzy pierwsze litery ich angielskich nazw lub jako liczby (dni tygodnia liczymy od 1: poniedziałek = 1, wtorek = 2 itd.).
Znak * oznacza każdą wartość, a znak ? oznacza niesprecyzowaną wartość. Użyć możemy jej kiedy np. chcemy wywoływać usługę w każdy piątek miesiąca i nie interesuje nas jakie to będą dni, to na 4 pozycji ustawiamy ?. Tak samo jeśli chcemy wywoływać usługę każdego 5 dnia miesiąca nie zważając na to jaki to będzie dzień tygodnia, to na 6 pozycji ustawiamy ?.
Poniżej parę przykładów:
* 9 12 * * *- co sekundę przez minutę od godz. 12:09:00 każdego dnia0 0 2-4 * * *- godz.2:00:00, 3:00:00 i 4:00:00 każdego dnia0 * 6,19 * * 2- 6:00:00 i 19:00:00 w każdy wtorek0 0/30 10 * JAN *- 10:00:00, 10:30:00 każdego dnia stycznia0 0 12 * * MON-FRI- 12:00:00 od poniedziałku do piątku0 0 0 3 5 ?- każdego 3 maja o północy
2. fixedDelay Czas w milisekundach pomiędzy ostatnio zakończonym zadaniem a rozpoczęciem następnego. Poprzednie zadanie musi być zakończone. 3. fixedDelayString Tak samo jak fixedDelay, ale parametr jest typu String, a nie long. 4. fixedRate Czas w milisekundach pomiędzy wywołaniami zadań. Poprzednie zadanie nie musi być zakończone. 5. fixedRateString Tak samo jak fixedRate, ale parametr jest typu String, a nie long. 6. initialDelay Opóźnienie w milisekundach przed wykonaniem pierwszego zadania fixedRate() lub fixedDelay(). 7. initialDelayString Tak samo jak initialDelay, ale parametr jest typu String, a nie long. 8. zone Strefa czasowa, dla której zadanie będzie wykonywane.
Zmiana parametru @Scheduled w trybie runtime:
Wartość parametru adnotacji @Scheduled można ustawić w trakcie działania programu. Można wykorzystać do tego metodę configureTasks z interfejsu SchedulingConfigurer. Przyjmuje ona w parametrze obiekt klasy ScheduledTaskRegistrar, na którym możemy wywołać metody pozwalające nam zmienić interesujący nas parametr. Do powyższego przykładu dodałam klasę konfiguracyjną, w której po 20 sekundach od uruchomienia programu wartość fixedRate zmienia się z 5 sekund na 1. Zamiast wykorzystanej przeze mnie metody addFixedRateTask możemy użyć addFixedDelayTask lub addTriggerTask. Więcej szczegółów TUTAJ.
@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
@Bean
public ScheduledTask scheduledTask() {
return new ScheduledTask();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
final LocalDateTime dateChange = LocalDateTime.now().plusSeconds(20);
taskRegistrar.addFixedRateTask(new Runnable() {
@Override
public void run() {
if(LocalDateTime.now().isAfter(dateChange)) {
scheduledTask().executeTask();
}
}
}, 1000);
}
}
Wynik działania zmodyfikowanego programu poniżej. Przez 20 pierwszych sekund (14:55:46-14:56:06) task uruchamiany jest co 5 sekund, a później co 1 sekundę.
Cały projekt można znaleźć TUTAJ. Scheduling wykorzystać możemy przy cyklicznym wysyłaniu maili (np. przy wysyłaniu ofert). Jeżeli chcecie się dowiedzieć czegoś więcej zapraszam TUTAJ.
Zachęcam również do obejrzenia video: