[Spring Batch] Quartz의 개념과 예시
Quartz란?
스프링 프레임워크와 통합되어 스프링 애플리케이션에서 스케줄링 작업을 수행할 수 있도록 지원하는 오픈소스 라이브러리이다.
스프링에서 Quartz를 사용하기 위해서는 의존성을 추가 하고, Quartz 스케줄러를 스프링 빈으로 등록하고, Job과 Trigger를 스프링 빈으로 등록하여 스케줄러에서 사용할 수 있도록 설정해야 한다. 이를 위해 스프링에서는 QuartzJobBean과 CronTriggerFactoryBean 등의 클래스를 제공한다.
의존성 추가
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
Gradle
implementation 'org.springframework.boot:spring-boot-starter-quartz'
Quartz 설정 예시 (Spring Batch Job 기준)
Spring Batch와 Quartz와 연동을 하는 것이 힘들었다.
아무래도 Spring Batch와 Quartz가 공통적으로 Job을 갖고 있기 때문에 더 혼란이 있었던 것 같다.
Spring Batch의 예시를 제외하고 Quartz에 초점을 맞춰 어떻게 Spring Batch가 Quartz에 설정되어 실행될 수 있는지 알아보자.
SpringBatchJob.class
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
public class SpringBatchJob implements Job { // (1)
private final JobLauncher jobLauncher;
private final Job springBatchJob; // (2)
public SpringBatchJob(JobLauncher jobLauncher, Job springBatchJob) {
this.jobLauncher = jobLauncher;
this.springBatchJob = springBatchJob;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
JobParameters jobParameters = new JobParametersBuilder()
.addString("jobParameterKey", "jobParameterValue")
.toJobParameters();
jobLauncher.run(springBatchJob, jobParameters);
} catch (Exception e) {
e.printStackTrace();
throw new JobExecutionException(e);
}
}
}
(1) : 여기서의 Job은 Quartz의 Job을 의미하며, 해당 Job을 구현하여 Quartz 스케쥴러가 실행될 때 어떤 작업단위를 실행시킬 것인지 설정하게 된다.
(2) : 주입되고 있는 Job은 Spring Batch의 Job이다.
QuartzConfiguration.class
@Configuration
public class QuartzConfiguration {
private final JobLauncher jobLauncher;
private final Job springBatchJob;
public QuartzConfiguration(JobLauncher jobLauncher, Job springBatchJob) {
this.jobLauncher = jobLauncher;
this.springBatchJob = springBatchJob;
}
@Bean
public JobDetailFactoryBean jobDetail() {
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(SpringBatchJob.class); // (1)
jobDetailFactory.setDurability(true); // (2)
jobDetailFactory.setBeanName("springBatchJob"); // (3)
jobDetailFactory.setApplicationContextJobDataKey("applicationContext"); // (4)
jobDetailFactory.setJobDataMap(new JobDataMap()); // (5)
return jobDetailFactory;
}
@Bean
public CronTriggerFactoryBean trigger(JobDetail jobDetail) {
CronTriggerFactoryBean cronTriggerFactory = new CronTriggerFactoryBean();
cronTriggerFactory.setJobDetail(jobDetail); // (6)
cronTriggerFactory.setCronExpression("0 0 0 * * ?"); // (7) Cron 표현식으로 실행 주기 설정
return cronTriggerFactory;
}
@Bean
public SchedulerFactoryBean scheduler(Trigger trigger) {
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setTriggers(trigger); // (8)
return schedulerFactory;
}
}
- JobDetailFactoryBean : Quartz의 JobDetail을 생성하는 빈을 의미한다.
JobDetail은 실행될 Job에 대한 정보를 가진다.
예시에서는 jobDetailFactory 객체를 생성하고, 해당 Job의 클래스를 설정한다. 이때 SpringBatchJob.class를 설정하여 Quartz가 실행될 때 해당 Job을 실행하도록 지정한다. - CronTriggerFactoryBean : Quartz의 Trigger를 생성하는 빈을 의미한다. Trigger는 Job이 실행될 시간 및 주기를 정의한다. 예시에서는 cronTriggerFactory 객체를 생성하고, 해당 Trigger의 JobDetail을 설정한다. 또한, Cron 표현식을 설정하여 Job이 언제 실행될지를 지정한다.
(1) : setJobClass(SpringBatchJob.class) : Quartz에서의 Job의 구현체인 SpringBatchJob을 의존성 주입하여 JobDetail에서 해당 Job이 실행될 수 있도록 설정해준다.
QuartzConfiguration을 생성하여 Quartz의 Job을 구현한 클래스를 의존성 주입을 하여 사용함으로써 Spring Batch의 Job과 연동을 할 수 있다.
💡 Quartz에서는 Job을 실행하기 위해서는 JobDetail을 생성해야 한다. JobDetail은 실행될 Job의 세부 정보를 담고 있으며, 어떤 Job 클래스를 실행해야 하는지를 지정해야 한다.
(2) : setDurability(true) : Job이 지속성(Persistence)을 갖도록 설정합니다. 즉, 스케줄러가 실행을 완료한 후에도 해당 Job이 스케줄러에 의해 삭제되지 않고 유지된다.
스케줄링된 Job이 지속성을 갖도록 설정한다.
이 설정은 Quartz의 Job과 관련이 있으며, Spring Batch Job과는 직접적인 관련이 없다.
즉, Job이 한 번 실행되고 나서도 스케줄러에서 삭제되지 않고 지속됩니다. 이렇게 설정된 JobDetail은 다음에 스케줄러에 의해 다시 실행될 수 있다.
예를 들어, Quartz 스케줄러를 사용하여 매일 자정마다 특정 작업을 실행하려고 한다고 가정해보면, Quartz의 JobDetail을 지속성을 갖도록 설정하지 않은 경우, 작업이 실행된 후 JobDetail은 스케줄러에서 삭제된다. 따라서 다음 날 자정에 해당 작업이 다시 실행되지 않는다. 하지만 setDurability(true)를 호출하여 JobDetail에 지속성을 설정한 경우, 작업이 실행된 후에도 JobDetail이 스케줄러에 남아 있어 다음 날 자정에 다시 실행될 수 있다.
(3) : setBeanName("springBatchJob") : Job의 빈 이름을 설정한다. 이는 Spring ApplicationContext에서 Job을 식별하기 위해 사용한다.
(4) : setApplicationContextJobDataKey("applicationContext") : ApplicationContext를 JobDataMap에 저장할 때 사용할 키를 설정한다. 이를 통해 Quartz Job에서 Spring Bean을 사용할 수 있게 된다.
(5) : setJobDataMap(new JobDataMap()) : Job 실행에 필요한 데이터를 저장하기 위한 JobDataMap을 생성다.
(6) : setJobDetail(jobDetail) : JobDetail 오브젝트를 지정하여 해당 JobDetail에 연결된 Quartz Job의 실행 일정을 설정한다.
(7) : setCronExpression("0 0 0 * * ?") : Cron 표현식을 사용하여 실행 주기를 설정합니다. 예시에서는 매일 자정마다 실행되도록 설정되어 있다.
(8) : setTriggers(trigger) : 생성된 Trigger 오브젝트를 스케줄러에 지정하여 해당 Trigger에 의해 실행될 Job을 설정한다.
Quartz 개념
1. Job (Spring Batch에서의 Job과는 다른 Job을 의미) Job은 스케줄링 작업의 단위입니다. 스케줄링 작업을 수행하기 위한 실제 로직이 구현되어 있습니다. Job 인터페이스를 구현하여 스케줄링 작업을 정의할 수 있다.
→ Quartz와 Spring Batch를 사용
2. Trigger Trigger는 Job을 실행하는 시점을 정의한다. 스케줄링 작업을 언제 실행할지를 결정하는 역할을 한다. SimpleTrigger, CronTrigger 등 다양한 종류의 Trigger가 제공된다.
3. Scheduler Scheduler는 Job과 Trigger를 관리하고 실행하는 역할을 한다. 스케줄링 작업을 등록하고 실행하는 등의 작업을 수행한다. 스케줄러를 생성하고 시작하는 방법은 다음과 같다.
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
4. JobDetail JobDetail은 Job을 실행하기 위한 상세 정보를 정의합니다. Job의 이름, 그룹, 실행 주기 등의 정보를 포함한다.
5. JobExecutionContext Quartz에서 실행되는 Job에 전달되는 매개변수와 상태 정보를 포함한다. Quartz의 Job이 실행될 때, JobExecutionContext는 해당 Job의 실행 컨텍스트를 제공한다.
6. JobDataMap JobDataMap은 JobExecutionContext에 전달되는 매개변수를 저장하는 맵이다. Job에서 필요한 매개변수를 저장하고 가져와 사용할 수 있다.