개요
2022년 5월 12일일에 작성한 글입니다. (링크)
Quartz Job Scheduler
Quartz Job Scheduler는 오픈소스 스케줄러입니다.
쿼츠는 자바 환경의 규모와 상관없이 사용이 가능하고 잡 실행에 유용한 스프링 부트 지원과 같이 오래전부터 스프링 연동을 지원합니다.
의존성 추가 (maven dependency)
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
pom.xml에 dependency를 추가합니다. 만약 Library를 사용할 경우 jar를 다운받아 추가합니다.
Job 과 Task
Quartz는 일반 클래스로 동작하기 때문에 Spring DI를 사용할 수 없습니다.
따라서 @Autowired를 통해 Service를 호출하여도 null이 출력되며 동작하지 않습니다.
이를 해결하기 위해 Job 과 Task를 분리하여 코드를 작성해보겠습니다.
package com.study.common.batch.test;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class TestBatchJob extends QuartzJobBean {
private TestBatchTask testBatchTask;
@Autowired
public void setTestBatchTask(TestBatchTask testBatchTask) {
this.testBatchTask = testBatchTask;
}
@Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
testBatchTask.task();
}
}
Task를 주입하여 Spring DI 컨테이너가 사용할 수 있는 실제 작업이 일어나는 객체입니다.
스케줄러에 의해 Job 클래스가 호출되었을 때 해당 executeInternal 메소드를 실행합니다.
package com.study.common.batch.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.study.common.service.CommonService;
public class TestBatchTask {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
CommonService commonService;
// Scheduling
public void task() {
log.info("Spring Quartz Scheduler executed!");
try {
/* Task 작성 */
} catch (Exception e) {
logger.error("Error : {}", e.getMessage());
}
}
}
빈(Bean)으로 등록된 TestBatchTask 객체는 의존성 주입을 통해 Service 객체 사용이 가능합니다.
실제 스케줄링이 일어났을 때 task() 메소드가 실행됩니다.
Batch Context (batch-context.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Task bean 생성 -->
<bean id="testBatchTask" class="com.study.common.batch.TestBatchTask" />
<!-- Job -->
<bean name="testBatchJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.study.common.batch.TestBatchJob" />
<!-- Task -->
<property name="jobDataAsMap">
<map>
<entry key="testBatchTask" value-ref="testBatchTask" />
</map>
</property>
</bean>
<!-- quartz trigger 작성 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="testBatchJob" />
<!-- 1분마다 실행 -->
<property name="cronExpression" value="0 0/1 * * * ?" />
</bean>
<!-- quartz trigger 실행 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
</list>
</property>
</bean>
</beans>
<!-- Task bean 생성 -->
<bean id="testBatchTask" class="com.study.common.batch.TestBatchTask" />
Spring IoC 컨테이너가 관리할 수 있도록 TestBatchTask 객체를 빈(Bean)으로 등록합니다.
<!-- Job -->
<bean name="testBatchJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.study.common.batch.TestBatchJob" />
<!-- Task -->
<property name="jobDataAsMap">
<map>
<entry key="testBatchTask" value-ref="testBatchTask" />
</map>
</property>
</bean>
JobDetailFactoryBean 클래스에 스케줄링하기 위한 Job 클래스를 주입합니다.
jobDataAsMap에 Service를 작성하는 것이 아니라 실제로 작업할 Task 하나만 작성하여 사용합니다. (작업하는데 필요한 빈 객체(Bean)를 value-ref를 통해 참조)
<!-- quartz trigger 작성 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="testBatchJob" />
<!-- 1분마다 실행 -->
<property name="cronExpression" value="0 0/1 * * * ?" />
</bean>
<!-- quartz trigger 실행 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
</list>
</property>
</bean>
스케줄러는 CronTrigger 방식으로 사용했으며, cronExpression을 설정하여 주기를 설정합니다. 이후 SchedulerFactoryBean을 통해 트리거를 등록해줍니다.
[Spring 레퍼런스] 26장 태스크(Task) 실행과 스케줄링
[스프링 배치] 쿼츠 Quartz 사용하여 배치 스케줄링
Quartz Job Scheduler란?
'DEVELOPMENT > Spring Framework' 카테고리의 다른 글
[Spring] 전시 티켓 환불 로직 개선기 (0) | 2025.02.02 |
---|---|
[Spring] COOLSMS + Redis 문자 인증, 회원가입 똑똑하게 구현하기 (작성 중..) (0) | 2024.06.17 |