Merhabalar arkadaşlar. Bu yazıda size Spring Boot tabanlı bir projede planlanmış görevlerin nasıl çalıştırılacağını anlatacağım. Bu yazıda konuyu anlatmak için kullandığım kaynak kodlara https://github.com/ilkgunel/SchedulingTaksWithSpring adresinden erişebilirsiniz.

Scheduling Mekanizmasının Aktif Hale Getirilmesi

Spring Boot tabanlı projelerimizi bildiğiniz üzere main(…) metoda sahip bir class üzerinden başlatabiliyoruz. @SpringBootApplication anotasyonu ile işaretlenmiş sınıfımızı bir de @EnableScheduling notasyonu ile işaretlersek projemizde Scheduling mekanizması aktif hale gelmiş olur.

Örnek kodumuz şöyle olacaktır:

package com.ilkaygunel.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@ComponentScan(basePackages = { "com.ilkaygunel.*" })
@EnableScheduling
public class Application {
	public static void main(String[] args) throws Exception {
		SpringApplication.run(Application.class);
	}
}

Spring Framework bize 4 adet Scheduling tipi sunuyor. Şimdi ayrı örneklerle bu 4 çeşit Scheduling mekanizmasını öğrenelim.

Fixed Rate Scheduling

Fixed Rate Scheduling ile sabit bir aralıkta çalışmasını istediğimiz görevleri çalıştırabiliiz. Örneğin Fixed Rate Scheduling ile ayarladığımız bir task her 5 saniyede bir tekrar tekrar çalışacaktır. Örnek kodumuz şöyle:

package com.ilkaygunel.tasks;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class FixedRateScheduledTask {

	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

	@Scheduled(fixedRate = 5000)
	public void fixedRateScheduledTaskMethod() {
		System.out.println("Fixed Rate Scheduled Task Worked! " + dateFormat.format(new Date()));
	}
}

@Scheduled anotasyonu ile bu metodun planlanmış bir zaman diliminde kendi kendine sürekli çalışacak bir metot olduğunu bildiriyoruz. İçerisine verdiğimiz fixedRate parametresi bu metodun sabit bir aralıkta sürekli çalışacağı anlamına geliyor. fixedRate parametresine verdiğimiz 5000 değeri de milisaniye cinsinden bir değerdir ve fixedRateScheduledTaskMethod() metodu her 5 saniyede bir çalışacaktır.

Uygulamayı çalıştırıp konsolu kontrol ettiğimiz zaman Started Application yazısından önce, uygulamamız ayağa kalkarken task’ımızın çalıştığını görüyoruz. Akabinde vermiş olduğumuz 5 saniyelik aralık uygulanmış ve Started Application yazısının hemen altında task’ımız bir kez daha çalışmış. Devam eden süreçte de her 5 saniyede bir task’ımız çalışıyor.

Fixed Delay Scheduling

Eğer planlı çalışmasını istediğiniz bir task’ın çalışması için bir önceki tetiklenmesinin bitmesini istiyorsak eğer Fixed Delay Scheduling kullanabiliriz. Bu tip kullanımda planladığımız task’ın yeniden çalışabilmesi için önceki task’ın bitmiş olması gerekir ve verdiğimiz süre task’ın bitiş zamanından itibaren sayılmaya başlanır.

Şu örnek koda bakalım:

package com.ilkaygunel.tasks;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class FixedDelayScheduledTask {

	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

	@Scheduled(fixedDelay = 2000)
	public void fixedDelayScheduledTaskMethod() {
		System.out.println("fixedDelayScheduledTaskMethod Task Worked! " + dateFormat.format(new Date()));
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (Exception e) {
			System.out.println("Ran into an error {}" + e);
			throw new IllegalStateException(e);
		}
	}
}

fixedDelayScheduledTaskMethod metodunu yine @Schedule notasyonu ile işaretliyoruz fakat bu kez içerisine fixedDelay parametresini veriyoruz ve değer olarak 2 saniyeyi geçiriyoruz. Böylece bu task bittikten 2 saniye sonra task yeniden tetiklenmiş olacak. Metot içerisinde ise 5 saniyelik bir bekletme işlemi uyguluyoruz. Böylece fixedDelay ile tanımlanmış metodun gerçekten bir sonraki task tetiklemesi için bekleyip beklemeyeceğini test etmiş olacağız.

Şimdi şu konsol çıktısına bakalım:

Konsol çıktımızda gördüğümüz gibi Tomcat ayağa kalkarken Started Application yazısından önce fixedDelayScheduledTaskMethod task’ı bir kez çalışıyor. Metot çalışınca 5 saniye uyuyor ve bitince 2 saniye de diğer task’ın çalışması için bekliyor. Toplamda 7 saniye sonra Started Application yazısının altında task’ın ikinci defa çalıştığını görüyoruz. Bu noktadan sonra task her iki task arasındaki 2 saniye ve 5 saniyelik uyuma zamanı ile toplamda 7 saniye aralıkla sürekli çalışıyor. Tabii ki burada 5 saniyelik sabit uyuma süresi var, başka bir projemizde database’de okuma yazma yavaşlığı olabilir, bağlandığımız bir servis geç cevap verebilir, bu süre hep değişkenlik gösterebilir.

Fixed Rate Or Delay And Initial Delay Scheduling

Eğer bir task’ın uygulama ayağa kalkarken çalışmasını istemiyor, uygulama tam olarak ayağa kalktıktan bir süre sonra çalışmasını sitiyorsak o zaman az önce gördüğümüz 2 kullanım tipi ile birlikte initialDelay parametresini de kullanabiliriz.

Şu örnek koda bakalım:

package com.ilkaygunel.tasks;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class FixedRateDelayAndInitialDelay {
	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

	@Scheduled(fixedRate = 2000, initialDelay = 5000)
	public void fixedRateDelayAndInitialDelay() {
		System.out.println("Fixed Rate Delay And Initial Delay Task Worked! " + dateFormat.format(new Date()));
	}
}

fixedRateDelayAndInitialDelay metodunu yine @Schedule notasyonu ile işaretliyoruz fakat bu kez 2 parametre veriyoruz. fixedRate yukarıda öğrendiğimiz şekilde 2 task arasında sabit zaman koyuyor. initialDelay parametresi uygulama başlatıldıktan kaç saniye sonra bu task’ın ilk defa çalıştırılacağını belirtiyor. Uygulama başladıktan 5 saniye sonra task ilk kez çalışacak.

Konsol çıktımızı inceleyelim:

Konsol çıktısından görebileceğimiz gibi uygulama ayağa kalkarken task tetiklenmedi, fakat uygulama ayağa kalktıktan 5 saniye sonra ilk task tetiklendi ve akabinde her 2 saniyede bir task tetiklenir oldu.

Using Cron Expression Scheduling

Eğer task’larımızı Cron Expression’lar ile planlamak istersek o zaman da @Scheduled notasyonuna cron parametresini geçirmemiz yeterli olacaktır. İlgili task’ın her dakika başı çalışmasını sağlayacak olan şu kod örneğine bakalım:

package com.ilkaygunel.tasks;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTaskUsingCronExpression {

	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

	@Scheduled(cron = "0 * * * * ?")
	public void scheduledTaskUsingCronExpression() {
		System.out.println("Scheduled Task Using Cron Expression Task Worked! " + dateFormat.format(new Date()));
	}
}

scheduledTaskUsingCronExpression metodumuzu yine @Scheduled notasyonu ile işaretledik ve içerisine bu kez Cron Expression kullanacağımız için cron parametresini verdik. 0 * * * * ? şablonundaki değer ilgili task’ın her dakika başı çalışmasını sağlayan bir değerdir. Örneğin her 5 saniyede bir task’ın çalışmasını istese idik de */5 * * * * * şeklinde bir şablonu kullanabilirdik. Ya da her gün öğleden sonra 15:30’da (3:30 PM) task’ın tetiklenmesini istese idik 0 30 15 * * * şeklinde bir Cron Expression kullanabilirdik. Aşağıdaki konsol çıktılarından ilki her dakika başı çalışan Cron Expression için bir örnek iken, ikincisi her 5 saniyede bir çalışan için bir örnektir.

Her dakika başı çalışan Cron Expression İçin Konsol Çıktısı:

Her 5 saniyede bir çalışan Cron Expression İçin Konsol Çıktısı:

Bu yazıda anlatacaklarım bu kadar arkadaşlar. Spring’in Scheduling mekanizmasının 4 farklı kullanım yöntemini öğremiş olduk. Başka bir yazıda görüşmek üzere.

Görüşene kadar sağlıcakla kalın.

Selam ve Sevgilerimle