Java/Spring Boot

[Java] Spring Boot Quartz 상세 이해하기 -2 : 주요 메서드 및 흐름, 처리과정

adjh54 2024. 2. 29. 09:51
반응형
해당 글에서는 Spring Boot Quartz에 대해 주요 메서드와 흐름, 처리과정에 대해 알아봅니다.





💡 [참고] Spring Boot Quartz의 이론에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
 

[Java] 스케줄링 & Spring Boot Quartz 이해하고 적용하기 -1 : 설정 및 간단예시

해당 글에서는 스케줄링에 대해 이해하고 Spring Boot Starter Quartz를 이용하여 스케줄링을 구성하는 간단한 예시를 구성하는 방법을 위한 목적으로 작성한 글입니다. 💡 스케줄러를 이해하기 이전

adjh54.tistory.com

 

 

1) Spring Boot Quartz


💡 Spring Boot Quartz

- Java 기반의 오픈 소스 작업 '스케줄링 라이브러리'를 의미합니다. 이를 사용하면 특정시간에 작업을 실행하거나 특정 간격으로 작업을 수행할 수 있습니다.

-이를 사용하면 시스템의 자동화 및 효율성 향상에 기여하며 백그라운드 작업을 수행하는 서비스, 이메일 발송 스케줄링, 데이터베이스 백업 등에 활용될 수 있습니다.

 

 

1. 주요 클래스 및 인터페이스


용어 분류 설명
Job 인터페이스 실행할 작업을 정의하는 인터페이스
JobDetail 인터페이스 실행될 작업을 정의하고 구성하는 인터페이스
JobBuilder 클래스 JobDetail 인스턴스를 생성하는데 사용되는 유틸리티 클래스
JobListener 인터페이스 작업의 생명 주기 동안 발생하는 이벤트를 처리하는 인터페이스
JobDataMap 클래스 작업 실행시 필요한 데이터를 저장하는 맵
     
Trigger 인터페이스 작업의 실행 시간을 결정하는 인터페이스
CronTrigger 인터페이스 복잡한 실행 스케줄을 정의할 수 있는 Trigger 인터페이스
TriggerBuilder 클래스 Trigger 인스턴스를 생성하는데 사용되는 유틸리티 클래스
SimpleScheduleBuilder 클래스 간단한 실행 스케줄을 정의할 수 있는 클래스
CronScheduleBuilder 클래스 복잡한 실행 스케줄을 cron 표현식으로 정의할 수 있는 클래스
     
Scheduler 인터페이스 작업과 트리거를 관리하고 실행하는 인터페이스
SchedulerFactory 클래스 Scheduler 인스턴스를 생성하는 클래스

 

 

 

 

2) Job


💡 Job

- 스케줄러에서 사용되는 Job은 JobDetail 객체를 구성하기 위해 JobBuilder로 구성하며, 해당 JobBuilder에는 Job의 인터페이스를 MyJob이라는 클래스에서 구현체로 ‘수행해야 하는 작업’을 작성하여 Builder를 구성하여 사용합니다.

 

 

1. Job


💡 Job

- Quarz에서 ‘실행 할 작업을 정의’하는 인터페이스입니다. 실행할 작업은 클래스를 생성하고 해당 Job 인터페이스의 구현체로 작업을 정의하여 사용합니다.


- Job 인터페이스를 구현하여 자신이 실행하고자 하는 작업에 대해서 정의를 할 수 있으며 Quartz의 생명 주기에 따라 주기적으로 실행이 됩니다.

 

void execute(org.quartz.JobExecutionContext jobExecutionContext) throws org.quartz.JobExecutionException;

 

 

 

 

2. JobDetail


💡 JobDetail

- Quatz 스케줄러에 의해 실행되는 작업을 정의합니다. 해당 객체는 JobBuilder를 통해 구성하며 실행하려는 Job의 이름, 그룹, 클래스 타입 등의 정보를 구성합니다.

 

💡 JobDetail 사용예시

- JobDetail 인스턴스를 구성합니다. 이는 JobBuilder로 구성하며 newJob()메서드를 통해 MyJob라는 Job을 추가하고 withIdentity()를 통해 그룹을 지정하여 객체를 구성합니다.
JobDetail jobDetail = JobBuilder
        .newJob(MyJob.class)
        .withIdentity("myJob", "group1")
        .build();

 

 

 💡 [참고] JobDetail API Document
메서드 이름 반환 값 설명
getKey() JobKey Job의 Key를 반환합니다.
getDescription() String Job의 설명을 반환합니다.
getJobClass() Class Job의 구현 클래스를 반환합니다.
getJobDataMap() JobDataMap Job의 data map을 반환합니다.
isDurable() boolean Job이 지속적으로 저장되는지 여부를 반환합니다.
isPersistJobDataAfterExecution() boolean Job이 실행 후 data map을 지속적으로 저장하는지 여부를 반환합니다.
isConcurrentExectionDisallowed() boolean 동시에 여러 Job이 실행되는 것을 허용하는지 여부를 반환합니다.
requestsRecovery() boolean Job이 실패한 경우 다시 실행하도록 설정되어 있는지 여부를 반환합니다.
 

JobDetail (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

Conveys the detail properties of a given Job instance. JobDetails are to be created/defined with JobBuilder. Quartz does not store an actual instance of a Job class, but instead allows you to define an instance of one, through the use of a JobDetail. Jobs

www.quartz-scheduler.org

 

 

💡 [참고] Builder 패턴에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
 

[Java] 생성자 패턴 이해하기 : 점층적 생성자, 자바 빈즈, Builder 패턴)

해당 글에서는 생성자 패턴에 대해서 이해하고, 어떤 패턴으로 생성자를 구성하는 것이 좋을지에 대해서 공유합니다. 1) 생성자 패턴의 종류 1. 점층적 생성자 패턴 (Telescoping Constructor Pattern) 💡

adjh54.tistory.com

 

 

3. JobBuilder


💡 JobBuilder

- Quartz 스케줄러에서 사용하는 유용한 유틸리티 클래스로 JobDetail 인스턴스를 생성하는데 사용됩니다.
- JobBuilder를 사용하면 JobDetail 객체를 쉽게 생성하고 작업의 이름, 그룹, 클래스 타입 등의 세부 정보를 설정할 수 있습니다.

 

💡 [참고] JobBuilder API Document
메서드 이름 반환 값 설명
build() JobDetail 이 JobBuilder가 정의한 JobDetail 인스턴스를 생성합니다.
newJob() JobBuilder JobDetail을 정의하기 위한 JobBuilder 인스턴스를 반환합니다.
newJob(Class jobClass) JobBuilder JobDetail을 정의하고, 실행할 Job의 클래스 이름을 설정하기 위한 JobBuilder 인스턴스를 반환합니다.
ofType(Class jobClazz) JobBuilder Trigger가 이 JobDetail과 연결되어 발화될 때 인스턴스화되고 실행되는 클래스를 설정합니다.
requestRecovery() JobBuilder '복구' 또는 '대체' 상황이 발생했을 때 Job이 다시 실행되어야 하는지 여부에 대한 스케줄러에 지시합니다.
requestRecovery(boolean jobShouldRecover) JobBuilder '복구' 또는 '대체' 상황이 발생했을 때 Job이 다시 실행되어야 하는지 여부에 대한 스케줄러에 지시합니다.
setJobData(JobDataMap newJobDataMap) JobBuilder 주어진 JobDataMap으로 JobDetail의 JobDataMap을 대체합니다.
storeDurably() JobBuilder Job이 영구적으로 저장되어야 하는지 여부를 설정합니다.
storeDurably(boolean jobDurability) JobBuilder Job이 영구적으로 저장되어야 하는지 여부를 설정합니다.
usingJobData(JobDataMap newJobDataMap) JobBuilder 주어진 JobDataMap의 모든 데이터를 JobDetail의 JobDataMap에 추가합니다.
usingJobData(String dataKey, Boolean value) JobBuilder 주어진 키-값 쌍을 JobDetail의 JobDataMap에 추가합니다.
usingJobData(String dataKey, Double value) JobBuilder 주어진 키-값 쌍을 JobDetail의 JobDataMap에 추가합니다.
usingJobData(String dataKey, Float value) JobBuilder 주어진 키-값 쌍을 JobDetail의 JobDataMap에 추가합니다.
usingJobData(String dataKey, Integer value) JobBuilder 주어진 키-값 쌍을 JobDetail의 JobDataMap에 추가합니다.
usingJobData(String dataKey, Long value) JobBuilder 주어진 키-값 쌍을 JobDetail의 JobDataMap에 추가합니다.
usingJobData(String dataKey, String value) JobBuilder 주어진 키-값 쌍을 JobDetail의 JobDataMap에 추가합니다.
withDescription(String jobDescription) JobBuilder Job의 설명(사람이 이해할 수 있는)을 설정합니다.
withIdentity(JobKey jobKey) JobBuilder JobKey를 사용하여 JobDetail을 식별합니다.
withIdentity(String name) JobBuilder 주어진 이름과 기본 그룹을 가진 JobKey를 사용하여 JobDetail을 식별합니다.
withIdentity(String name, String group) JobBuilder 주어진 이름과 그룹을 가진 JobKey를 사용하여 JobDetail을 식별합니다.
 

JobBuilder (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

Use a JobKey with the given name and group to identify the JobDetail. If none of the 'withIdentity' methods are set on the JobBuilder, then a random, unique JobKey will be generated.

www.quartz-scheduler.org

JobDetail jobDetail = JobBuilder
        .newJob(MyJob.class)                   // Job의 구현 클래스 설정
        .withIdentity("myJob", "group1")        // Job의 identity 설정
        .withDescription("This is my job")      // Job의 설명 설정
        .ofType(MyJob.class)                   // Job의 구현 클래스 설정
        .requestRecovery(true)                  // Job이 실패한 경우 다시 실행하도록 설정
        .storeDurably(true)                     // Job이 지속적으로 저장되도록 설정
        .usingJobData("key", "value")           // Job의 data map 설정
        .build();                               // 설정된 정보를 바탕으로 JobDetail 인스턴스 생성

 

 

 

 

4. JobListener


💡 JobListener

- 스프링 배치에서 제공하는 인터페이스로 배치 작업의 생명주기 동안 발생하는 이벤트를 처리합니다. 이 인터페이스를 구현함으로써 개발자는 배치 작업이 시작되거나 완료될 때마다 특정 작업을 수행하도록 할 수 있습니다.

- 예를 들어, 작업이 시작될 때 데이터베이스에 로그를 기록하거나, 작업이 완료된 후에 이메일 알림을 보내는 등의 작업을 수행할 수 있습니다. 이러한 기능은 배치 작업의 상태를 모니터링하고, 문제가 발생했을 때 즉시 알아차릴 수 있도록 돕습니다.
메서드 반환 값 설명
getName() String JobListener의 이름을 반환합니다.
jobToBeExecuted() void Job이 실행되기 직전에 호출되는 메서드로, Job의 실행 준비 상황을 확인하거나 필요한 작업을 수행하는 데 사용할 수 있습니다.
jobExecutionVetoed() void 다른 JobListener가 Job의 실행을 방해(veto)했을 때 호출되는 메서드입니다.
jobWasExecuted() void Job의 실행이 완료된 후에 호출되는 메서드로, Job의 실행 결과를 로깅하거나 후속 작업을 수행하는 데 사용할 수 있습니다.
public interface JobListener {
    java.lang.String getName();

    void jobToBeExecuted(org.quartz.JobExecutionContext jobExecutionContext);

    void jobExecutionVetoed(org.quartz.JobExecutionContext jobExecutionContext);

    void jobWasExecuted(org.quartz.JobExecutionContext jobExecutionContext, org.quartz.JobExecutionException e);
}

 

 

💡 사용예시
package com.adjh.testproject;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

/**
 * Job 생명주기동안에 발생하는 이벤트를 처리합니다.
 *
 * @author : jonghoon
 * @fileName : MyJobListener
 * @since : 2/26/24
 */
public class MyJobListener implements JobListener {
    @Override
    public String getName() {
        return "MyJobListener";
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        System.out.println("Job 실행되기 이전에 수행됩니다.");
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
        System.out.println("Job 실행이 실패하였을때 수행됩니다.");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        System.out.println("Job 실행 이후에 수행됩니다.");
    }
}

 

 

💡 사용예시

- 구성한 JobListener를 스케줄러 내에 추가하여 scheduler가 실행되는 동안 Job의 생명주기를 확인 할 수 있습니다.
public static void main(String[] args) throws SchedulerException {

        JobDetail jobDetail = JobBuilder
                .newJob(MyJob.class)                   // Job의 구현 클래스 설정
                .withIdentity("myJob", "group1")        // Job의 identity 설정
                .withDescription("This is my job")      // Job의 설명 설정
                .ofType(MyJob.class)                   // Job의 구현 클래스 설정
                .requestRecovery(true)                  // Job이 실패한 경우 다시 실행하도록 설정
                .storeDurably(true)                     // Job이 지속적으로 저장되도록 설정
                .usingJobData("key", "value")           // Job의 data map 설정
                .build();                               // 설정된 정보를 바탕으로 JobDetail 인스턴스 생성

        // Trigger 생성
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(10)
                        .repeatForever())
                .build();

        // 스케줄러 생성 및 Job, Trigger 등록
        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        MyJobListener myJobListener = new MyJobListener();
        scheduler.getListenerManager().addJobListener(myJobListener);       // JobListener 등록
        scheduler.start();
        scheduler.scheduleJob(jobDetail, trigger);
    }

 

 

 

5. JobDataMap


 

💡 JobDataMap

- Quartz 스케줄러에서 Job의 상태 데이터를 관리하는 데 사용되는 클래스입니다. 이 클래스는 키와 값의 쌍으로 이루어진 데이터를 저장하는 Map 인터페이스를 확장한 것입니다.
메서드 이름 반환 값 설명
getBooleanFromString(String key) Boolean JobDataMap에서 식별된 Boolean 값을 가져옵니다.
getBooleanValue(String key) boolean JobDataMap에서 식별된 boolean 값을 가져옵니다.
getBooleanValueFromString(String key) boolean JobDataMap에서 식별된 boolean 값을 가져옵니다.
getCharacterFromString(String key) Character JobDataMap에서 식별된 Character 값을 가져옵니다.
getCharFromString(String key) char JobDataMap에서 식별된 char 값을 가져옵니다.
getDoubleFromString(String key) Double JobDataMap에서 식별된 Double 값을 가져옵니다.
getDoubleValue(String key) double JobDataMap에서 식별된 double 값을 가져옵니다.
getDoubleValueFromString(String key) double JobDataMap에서 식별된 double 값을 가져옵니다.
getFloatFromString(String key) Float JobDataMap에서 식별된 Float 값을 가져옵니다.
getFloatValue(String key) float JobDataMap에서 식별된 float 값을 가져옵니다.
getFloatValueFromString(String key) float JobDataMap에서 식별된 float 값을 가져옵니다.
getIntegerFromString(String key) Integer JobDataMap에서 식별된 int 값을 가져옵니다.
getIntFromString(String key) int JobDataMap에서 식별된 int 값을 가져옵니다.
getIntValue(String key) int JobDataMap에서 식별된 int 값을 가져옵니다.
getLongFromString(String key) Long JobDataMap에서 식별된 Long 값을 가져옵니다.
getLongValue(String key) long JobDataMap에서 식별된 long 값을 가져옵니다.
getLongValueFromString(String key) long JobDataMap에서 식별된 long 값을 가져옵니다.
putAsString(String key, boolean value) void 주어진 boolean 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, Boolean value) void 주어진 Boolean 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, char value) void 주어진 char 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, Character value) void 주어진 Character 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, double value) void 주어진 double 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, Double value) void 주어진 Double 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, float value) void 주어진 float 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, Float value) void 주어진 Float 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, int value) void 주어진 int 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, Integer value) void 주어진 Integer 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, long value) void 주어진 long 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
putAsString(String key, Long value) void 주어진 Long 값을 Job의 데이터 맵에 문자열 버전으로 추가합니다.
 

JobDataMap (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

Holds state information for Job instances. JobDataMap instances are stored once when the Job is added to a scheduler. They are also re-persisted after every execution of jobs annotated with @PersistJobDataAfterExecution. JobDataMap instances can also be st

www.quartz-scheduler.org

 

 

💡 사용예시

- JobDataMap 인스턴스를 생성하고 키-값 쌍으로 추가하는 예시이며 JobDetail을 구성하는데 setJobData() 메서드를 통해서 JobDataMap을 추가합니다.
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("key", "value");

 JobDetail job = JobBuilder
                .newJob(FcmJob.class)                                   // Job 구현 클래스
                .withIdentity("fcmSendJob", "fcmGroup")     // Job 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Job")   // Job 설명
                .setJobData(jobDataMap)
                .build();

 

 

 

3) Trigger


💡 Trigger

- 스케줄러에서 사용되는 Trigger는 SimpleTrigger와 CronTrigger로 나뉩니다.

- SimpleTrigger는 Trigger로 인스턴스화 해야합니다. 이는 TriggerBuilder를 통해 구성하며 withSchedule() 메서드를 통해서 SimpleScheduleBuilder를 구성합니다.
- CronTrigger는 Trigger 혹은 CronTrigger로 인스턴스화해야 합니다. 이는 TriggerBuilder를 통해 구성하며 withSchedule() 메서드를 통해서 CronScheduleBuilder를 구성합니다.

 

1. Trigger


💡 Trigger

- Quartz의 Trigger는 스케줄링 작업의 실행 시간을 결정하는 역할을 합니다. Trigger는 간단히 말해 작업이 언제 실행될지를 정의하는 것입니다.
- Trigger 역시 JobDetail 객체와 비슷하게 TriggerBuilder로 인스턴스를 생성합니다.
- Quartz는 SimpleTrigger와 CronTrigger 두 가지 주요한 Trigger를 제공합니다.

1. SimpleTrigger
- 특정 시간에 시작하여 주기적으로 작업을 실행하도록 설정할 수 있습니다. 이때 실행 주기와 반복 횟수를 설정해야 합니다

2. CronTrigger
- UNIX cron 표현식을 사용하여 작업 실행 스케줄을 정의할 수 있습니다. 복잡한 실행 스케줄을 정의할 수 있으므로, 매주 특정 요일에 실행되거나 매월 특정 날에 실행되는 등의 스케줄을 설정할 수 있습니다.
 

Trigger (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

Instructs the Scheduler that the Trigger will never be evaluated for a misfire situation, and that the scheduler will simply try to fire it as soon as it can, and then update the Trigger as if it had fired at the proper time. NOTE: if a trigger uses this i

www.quartz-scheduler.org

 

 

💡 SimpleScheduleBuilder 사용예시

- Trigger를 인스턴스화 할때 TriggerBuilder를 사용하여 구성합니다.
- TriggerBuilder에서는 simpleSchedule을 사용하여 구성하였고 10초마다 영원히 반복되는 트리거를 사용하였습니다.
// Trigger 생성
Trigger trigger = TriggerBuilder
        .newTrigger()
        .withIdentity("myTrigger", "group1")
        .startNow()
        .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)
                .repeatForever())
        .build();

 

 

💡 CronScheduleBuilder 사용예시

- Trigger를 인스턴스화 할때 TriggerBuilder를 사용하여 구성합니다.

- TriggerBuilder에서는 cronSchedule을 사용하여 구성하였고 10초마다 반복되는 트리거를 사용하였습니다.
 Trigger trigger = TriggerBuilder
              .newTrigger()
              .withIdentity("fcmSendTrigger", "fcmGroup")         // Trigger 이름, 그룹 지정
              .withDescription("FCM 처리를 위한 조회 Trigger")       // Trigger 설명
              .startNow()
              .withSchedule(
                      CronScheduleBuilder
                              .cronSchedule("0/10 * * * * ?")
              )
              .build();

 

 

 

2. CronTrigger


💡 CronTrigger

- 작업을 주기적으로 실행하도록 설정하는 데 사용됩니다. 이는 UNIX의 cron 표현식을 사용하여 태스크의 실행 스케줄을 정의하며, 이를 통해 매우 복잡한 실행 스케줄을 설정할 수 있습니다.

- 예를 들어, 매주 특정 요일에 실행하거나, 매월 특정 날에 실행되는 등의 스케줄을 설정할 수 있습니다.

 

💡 사용예시

- 10초마다 수행하는 Trigger를 구성하였습니다.
 CronTrigger cronTrigger = TriggerBuilder
              .newTrigger()
              .withIdentity("fcmSendTrigger", "fcmGroup")         // Trigger 이름, 그룹 지정
              .withDescription("FCM 처리를 위한 조회 Trigger")     // Trigger 설명
              .startNow()
              .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")).build();

 

 

 

3. TriggerBuilder


💡 TriggerBuilder

- Quartz 스케줄러에서 트리거를 생성하는 데 사용되는 유틸리티 클래스입니다. 이 클래스를 사용하면 트리거의 다양한 속성을 설정하고, 최종적으로 트리거 인스턴스를 생성할 수 있습니다.

- TriggerBuilder를 사용하여 트리거 이름, 그룹, 연관된 작업, 시작 시간, 종료 시간, 스케줄, 우선순위 등을 설정할 수 있습니다. 또한, JobDataMap을 사용하여 트리거가 실행될 때 필요한 추가 데이터를 제공할 수 있습니다.

TriggerBuilder는 SimpleTriggerBuilder와 CronTriggerBuilder 같은 여러 하위 클래스를 가지고 있습니다

1. SimpleTriggerBuilder

- 트리거가 특정 시간에 시작하여 일정한 간격으로 반복 실행되도록 설정할 수 있습니다

2. CronTriggerBuilder

- 복잡한 스케줄 패턴을 정의할 수 있습니다.

 

💡 [참고] TriggerBuilder API Document
메서드 반환값 설명
newTrigger() TriggerBuilder 새로운 TriggerBuilder를 생성합니다.
withIdentity(String name) TriggerBuilder Trigger의 이름을 설정합니다.
withIdentity(String name, String group) TriggerBuilder Trigger의 이름과 그룹을 설정합니다.
forJob(JobDetail jobDetail) TriggerBuilder Trigger가 실행할 JobDetail을 설정합니다.
forJob(String jobName) TriggerBuilder Trigger가 실행할 작업의 이름을 설정합니다.
forJob(String jobName, String groupName) TriggerBuilder Trigger가 실행할 작업의 이름과 그룹을 설정합니다.
startNow() TriggerBuilder Trigger를 즉시 실행하도록 설정합니다.
startAt(Date startTime) TriggerBuilder Trigger가 시작되는 시간을 설정합니다.
endAt(Date endTime) TriggerBuilder Trigger가 종료되는 시간을 설정합니다.
withSchedule(ScheduleBuilder scheduleBuilder) TriggerBuilder Trigger의 스케줄을 설정합니다.
modifiedByCalendar(String calendarName) TriggerBuilder Trigger가 수정되는 달력의 이름을 설정합니다.
withPriority(int priority) TriggerBuilder Trigger의 우선순위를 설정합니다.
usingJobData(String key, String value) TriggerBuilder Trigger의 JobDataMap에 문자열 값을 설정합니다.
usingJobData(String key, int value) TriggerBuilder Trigger의 JobDataMap에 정수 값을 설정합니다.
usingJobData(JobDataMap newJobDataMap) TriggerBuilder Trigger의 JobDataMap을 새로운 JobDataMap으로 설정합니다.
build() Trigger 설정된 내용을 기반으로 Trigger를 생성합니다.
 

TriggerBuilder (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

TriggerBuilder is used to instantiate Triggers. The builder will always try to keep itself in a valid state, with reasonable defaults set for calling build() at any point. For instance if you do not invoke withSchedule(..) method, a default schedule of fir

www.quartz-scheduler.org

 

 

 

4. SimpleScheduleBuilder


💡 SimpleScheduleBuilder

- 일정을 쉽게 만들 수 있는 도구입니다. 사용자는 특정 일정의 시작시간, 종료시간, 그리고 반복되는 패턴을 설정할 수 있습니다.
- 또한, 각 일정에 대한 설명, 위치, 참가자 등의 정보를 추가할 수 있습니다. SimpleScheduleBuilder를 사용하면 복잡한 일정도 간편하게 관리할 수 있습니다.
메서드 반환값 설명
simpleSchedule() SimpleScheduleBuilder SimpleScheduleBuilder의 인스턴스를 생성합니다.
withIntervalInSeconds(int seconds) SimpleScheduleBuilder 작업의 실행 간격을 초 단위로 설정합니다.
withIntervalInMinutes(int minutes) SimpleScheduleBuilder 작업의 실행 간격을 분 단위로 설정합니다.
withIntervalInHours(int hours) SimpleScheduleBuilder 작업의 실행 간격을 시간 단위로 설정합니다.
withIntervalInMilliseconds(long milliseconds) SimpleScheduleBuilder 작업의 실행 간격을 밀리초 단위로 설정합니다.
withRepeatCount(int count) SimpleScheduleBuilder 작업의 반복 횟수를 설정합니다.
repeatForever() SimpleScheduleBuilder 작업을 무한히 반복하도록 설정합니다.
withMisfireHandlingInstructionIgnoreMisfires() SimpleScheduleBuilder misfire를 무시하고 작업을 실행하도록 설정합니다.
withMisfireHandlingInstructionFireNow() SimpleScheduleBuilder misfire가 발생하면 즉시 작업을 실행하도록 설정합니다.
withMisfireHandlingInstructionNextWithExistingCount() SimpleScheduleBuilder misfire가 발생하면 다음 반복 실행을 계획에 따라 수행하고, 반복 횟수는 변경하지 않습니다.
withMisfireHandlingInstructionNowWithExistingCount() SimpleScheduleBuilder misfire가 발생하면 즉시 작업을 실행하고, 반복 횟수는 변경하지 않습니다.
withMisfireHandlingInstructionNextWithRemainingCount() SimpleScheduleBuilder misfire가 발생하면 다음 반복 실행을 계획에 따라 수행하고, 남은 반복 횟수를 줄입니다.
withMisfireHandlingInstructionNowWithRemainingCount() SimpleScheduleBuilder misfire가 발생하면 즉시 작업을 실행하고, 남은 반복 횟수를 줄입니다.
 

SimpleScheduleBuilder (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

SimpleScheduleBuilder is a ScheduleBuilder that defines strict/literal interval-based schedules for Triggers. Quartz provides a builder-style API for constructing scheduling-related entities via a Domain-Specific Language (DSL). The DSL can best be utilize

www.quartz-scheduler.org

 

 

 

5. CronScheduleBuilder


💡 CronScheduleBuilder

- Quartz 스케줄러에서 CronTrigger를 생성하는 데 사용되는 유틸리티 클래스입니다. 이 클래스를 사용하면 복잡한 작업 실행 스케줄을 cron 표현식을 사용하여 쉽게 정의할 수 있습니다.
// CronTrigger 생성
CronTrigger cronTrigger = TriggerBuilder
        .newTrigger()
        .withIdentity("myCronTrigger", "group1")
        .withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * 1/1 * ? *"))
        .build();

 

💡 cronExpression 사용 예시
*    *    *    *    *
-    -    -    -    -
|    |    |    |    |
|    |    |    |    +----- 요일 (0 - 6) (0이나 7이 일요일)
|    |    |    +---------- 월 (1 - 12)
|    |    +--------------- 일 (1 - 31)
|    +-------------------- 시 (0 - 23)
+------------------------- 분 (0 - 59)

 

 

💡 cron 표현식 예시
Cron Expression 설명
* * * * * 매 분
*/30 * * * * 30분마다
30 5 * * * 매일 오전 5시 30분
30 5 * * 1 매주 월요일 오전 5시 30분
30 5 1 * * 매월 1일 오전 5시 30분

 

 

메서드 반환값 설명
cronSchedule(String cronExpression) CronScheduleBuilder cron 표현식을 사용하여 CronScheduleBuilder의 인스턴스를 생성합니다.
cronSchedule(CronExpression cronExpression) CronScheduleBuilder CronExpression 객체를 사용하여 CronScheduleBuilder의 인스턴스를 생성합니다.
dailyAtHourAndMinute(int hour, int minute) CronScheduleBuilder 매일 특정 시간에 작업을 실행하도록 설정합니다.
weeklyOnDayAndHourAndMinute(int dayOfWeek, int hour, int minute) CronScheduleBuilder 매주 특정 요일에 특정 시간에 작업을 실행하도록 설정합니다.
monthlyOnDayAndHourAndMinute(int dayOfMonth, int hour, int minute) CronScheduleBuilder 매월 특정 날에 특정 시간에 작업을 실행하도록 설정합니다.
yearlyOnDayAndHourAndMinute(int dayOfYear, int hour, int minute) CronScheduleBuilder 매년 특정 날에 특정 시간에 작업을 실행하도록 설정합니다.
inTimeZone(TimeZone timezone) CronScheduleBuilder 작업이 실행되는 시간대를 설정합니다.
withMisfireHandlingInstructionIgnoreMisfires() CronScheduleBuilder misfire를 무시하고 작업을 실행하도록 설정합니다.
withMisfireHandlingInstructionDoNothing() CronScheduleBuilder misfire가 발생하면 작업을 실행하지 않습니다.
withMisfireHandlingInstructionFireAndProceed() CronScheduleBuilder misfire가 발생하면 작업을 즉시 실행하고, 다음 스케줄에 따라 계속 진행합니다.
 

CronScheduleBuilder (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

CronScheduleBuilder is a ScheduleBuilder that defines CronExpression-based schedules for Triggers. Quartz provides a builder-style API for constructing scheduling-related entities via a Domain-Specific Language (DSL). The DSL can best be utilized through t

www.quartz-scheduler.org

 

 

 

4) Scheduler


💡 Scheduler

- 스케줄러에서 사용되는 Scheduler는 StdSchedulerFactory를 통해 스케줄러를 가져와서 Scheduler Job을 구성합니다. 또한 Job의 생명주기를 관리하는 JobListener를 등록할 수 있습니다.

- Scheduler Job에는 Job과 Trigger가 등록이 됩니다.

 

 

1. Scheduler


💡 Scheduler

- 여러 작업(Job)을 관리하고 이들을 트리거(Trigger)에 따라 실행합니다. 스케줄러는 작업의 실행 시간, 빈도 등을 제어하며, 필요에 따라 작업을 일시 중지하거나 재개할 수 있습니다.

- 또한, 스케줄러는 작업의 실행 상태를 추적하고 작업 완료 후의 후속 작업을 관리하는 등의 역할을 합니다.
메서드 리턴 타입 설명
addCalendar(calName, calendar, replace, updateTriggers) void 주어진 Calendar를 스케줄러에 추가(등록)합니다.
addJob(jobDetail, replace) void 주어진 Job를 스케줄러에 추가합니다. 이때 연관된 Trigger가 없습니다.
addJob(jobDetail, replace, storeNonDurableWhileAwaitingScheduling) void 주어진 Job를 스케줄러에 추가합니다. 이때 연관된 Trigger가 없습니다.
checkExists(jobKey) boolean 주어진 식별자를 가진 Job이 스케줄러 내에 이미 존재하는지 확인합니다.
checkExists(triggerKey) boolean 주어진 식별자를 가진 Trigger가 스케줄러 내에 이미 존재하는지 확인합니다.
clear() void 모든 스케줄링 데이터를 삭제합니다. 모든 Jobs, Triggers, Calendars를 삭제합니다.
deleteCalendar(calName) boolean 스케줄러에서 특정된 Calendar를 삭제합니다.
deleteJob(jobKey) boolean 스케줄러에서 특정된 Job을 삭제합니다. 이때 연관된 Triggers도 같이 삭제됩니다.
deleteJobs(jobKeys) boolean 스케줄러에서 특정된 Jobs를 삭제합니다. 이때 연관된 Triggers도 같이 삭제됩니다.
getCalendar(calName) Calendar 주어진 이름의 Calendar 인스턴스를 가져옵니다.
getCalendarNames() List<String> 모든 등록된 Calendars의 이름을 가져옵니다.
getContext() SchedulerContext 스케줄러의 SchedulerContext를 반환합니다.
getCurrentlyExecutingJobs() List<JobExecutionContext> 이 스케줄러 인스턴스에서 현재 실행 중인 모든 Jobs의 JobExecutionContext 객체 목록을 반환합니다.
getJobDetail(jobKey) JobDetail 주어진 키의 Job 인스턴스에 대한 JobDetail을 가져옵니다.
getJobGroupNames() List<String> 모든 알려진 JobDetail 그룹의 이름을 가져옵니다.
getJobKeys(matcher) Set<JobKey> 일치하는 그룹의 모든 JobDetails의 키를 가져옵니다.
getListenerManager() ListenerManager 스케줄러의 ListenerManager에 대한 참조를 가져옵니다. 이를 통해 리스너를 등록할 수 있습니다.
getMetaData() SchedulerMetaData 스케줄러 인스턴스의 설정과 기능을 설명하는 SchedulerMetaData 객체를 가져옵니다.
getPausedTriggerGroups() Set<String> 일시 중지된 모든 Trigger 그룹의 이름을 가져옵니다.
getSchedulerInstanceId() String 스케줄러의 인스턴스 ID를 반환합니다.
getSchedulerName() String 스케줄러의 이름을 반환합니다.
getTrigger(triggerKey) Trigger 주어진 키의 Trigger 인스턴스를 가져옵니다.
getTriggerGroupNames() List<String> 모든 알려진 Trigger 그룹의 이름을 가져옵니다.
getTriggerKeys(matcher) Set<TriggerKey> 주어진 그룹의 모든 Triggers의 이름을 가져옵니다.
getTriggersOfJob(jobKey) List<? extends Trigger> 특정된 JobDetail과 연관된 모든 Triggers를 가져옵니다.
getTriggerState(triggerKey) Trigger.TriggerState 특정된 Trigger의 현재 상태를 가져옵니다.
interrupt(jobKey) boolean 현재 이 스케줄러 인스턴스 내에서 실행 중인 특정 Job의 중단을 요청합니다. 이때 Job은 InterruptableJob 인터페이스의 구현체여야 합니다.
interrupt(fireInstanceId) boolean 현재 이 스케줄러 인스턴스 내에서 실행 중인 특정 Job 인스턴스의 중단을 요청합니다. 이때 Job은 InterruptableJob 인터페이스의 구현체여야 합니다.
isInStandbyMode() boolean 스케줄러가 대기 모드인지를 보고합니다.
isShutdown() boolean 스케줄러가 종료되었는지를 보고합니다.
isStarted() boolean 스케줄러가 시작되었는지를 보고합니다.
pauseAll() void 모든 트리거를 일시 중지합니다.
pauseJob(jobKey) void 주어진 키의 JobDetail을 일시 중지합니다.
pauseJobs(matcher) void 일치하는 그룹의 모든 JobDetails를 일시 중지합니다.
pauseTrigger(triggerKey) void 주어진 키의 Trigger를 일시 중지합니다.
pauseTriggers(matcher) void 일치하는 그룹의 모든 Triggers를 일시 중지합니다.
rescheduleJob(triggerKey, newTrigger) Date 주어진 키의 Trigger를 제거(삭제)하고 새로 주어진 Trigger를 저장합니다.
resetTriggerFromErrorState(triggerKey) void 특정된 Trigger의 현재 상태를 ERROR에서 NORMAL 또는 PAUSED로 재설정합니다.
resumeAll() void 모든 트리거를 재개합니다.
resumeJob(jobKey) void 주어진 키의 JobDetail을 재개합니다.
resumeJobs(matcher) void 일치하는 그룹의 모든 JobDetails를 재개합니다.
resumeTrigger(triggerKey) void 주어진 키의 Trigger를 재개합니다.
resumeTriggers(matcher) void 일치하는 그룹의 모든 Triggers를 재개합니다.
scheduleJob(jobDetail, triggersForJob, replace) void 주어진 job과 관련된 트리거 세트와 함께 job을 스케줄합니다.
scheduleJob(JobDetail jobDetail, Trigger trigger) Date 주어진 JobDetail을 스케줄러에 추가하고, 주어진 Trigger와 연결합니다.
scheduleJob(Trigger trigger) Date 주어진 Trigger로 작업을 스케줄링합니다. Trigger의 설정에 따라 Job이 실행됩니다.
scheduleJobs(Map<JobDetail, Set<? extends Trigger>> triggersAndJobs, boolean replace) void 주어진 모든 작업과 그에 관련된 Trigger들을 스케줄링합니다.
setJobFactory(JobFactory factory) void Job 인스턴스를 생성하는 데 책임질 JobFactory를 설정합니다.
shutdown() void Scheduler의 Trigger 발동을 중단하고, Scheduler와 관련된 모든 리소스를 정리합니다.
shutdown(boolean waitForJobsToComplete) void Scheduler의 Trigger 발동을 중단하고, Scheduler와 관련된 모든 리소스를 정리합니다.
standby() void Scheduler의 Trigger 발동을 일시 중단합니다.
start() void Trigger를 발동시키는 Scheduler의 스레드를 시작합니다.
startDelayed(int seconds) void 지정된 초 만큼 대기한 후 start()를 호출합니다.
triggerJob(JobKey jobKey) void 주어진 JobKey를 가진 Job을 즉시 실행합니다.
triggerJob(JobKey jobKey, JobDataMap data) void 주어진 JobKey를 가진 Job을 즉시 실행합니다.
unscheduleJob(TriggerKey triggerKey) boolean 스케줄러에서 지정된 Trigger를 제거합니다.

 

 

Scheduler (Quartz Enterprise Job Scheduler 2.3.0-SNAPSHOT API)

Request the interruption, within this Scheduler instance, of all currently executing instances of the identified Job, which must be an implementor of the InterruptableJob interface. If more than one instance of the identified job is currently executing, th

www.quartz-scheduler.org

 

 

2. StdSchedulerFactory


💡 StdSchedulerFactory

- Quartz 스케줄러의 가장 일반적인 구현체입니다. 이 클래스는 Scheduler 인스턴스를 생성하고 초기화하는 역할을 합니다.
- 설정 파일이나 직접 전달된 Properties 객체를 이용해 스케줄러를 설정할 수 있습니다. 또한, 스케줄러가 사용하는 스레드 풀, JobStore 등의 구성 요소를 관리하고 설정합니다.

 

메서드 명 반환 타입 설명
getScheduler() Scheduler Scheduler 인스턴스를 반환합니다. 만약 아직 스케줄러가 초기화되지 않았다면 초기화를 수행한 후 반환합니다.
getScheduler(String schedName) Scheduler 주어진 이름에 해당하는 Scheduler 인스턴스를 반환합니다.
getAllSchedulers() Collection<Scheduler> 현재 팩토리에 의해 생성된 모든 Scheduler 인스턴스들을 반환합니다.
initialize() void 기본 quartz.properties 파일을 사용해 스케줄러 팩토리를 초기화합니다.
initialize(String filename) void 주어진 파일 이름의 properties 파일을 사용해 스케줄러 팩토리를 초기화합니다.
initialize(Properties props) void 주어진 Properties 객체를 사용해 스케줄러 팩토리를 초기화합니다.

 

 

 

5) 환경 구성


 

1. 의존성 주입


 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-quartz:3.2.3'            // Spring Boot Quartz
}

 

 

2. Job 구성


💡 Job 구성

- Job 인터페이스의 구현체로 구성합니다. 해당 클래스는 실제 데이터 처리를 위한 작업 내용을 명시합니다.

- Job 인터페이스에서 제공하는 메서드인 execute() 내에 실제 데이터 처리를 위한 Job을 구성합니다.
package com.adjh.multiflexapi.scheduler.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;

/**
 * 실제 데이터 처리를 위한 Job을 구성합니다.
 *
 * @author : lee
 * @fileName : MyJob
 * @since : 2/28/24
 */
public class MyJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        System.out.println("실제 수행하는 Job 입니다.");
    }
}

 

 

3. JobListener 구성


💡 JobListener 구성

- JobListener 인터페이스의 구현체로 구성합니다. 해당 클래스에서는 Job이 실행 직전, 실행 완료, 실행중 오류가 발생하였을 때의 생명주기를 관리하는 클래스입니다.
메서드 명 반환 값 설명
getName String JobListener의 이름을 반환합니다.
jobToBeExecuted void Job이 실행되기 직전에 호출되는 메서드로, Job의 실행 준비 상황을 확인하거나 필요한 작업을 수행하는 데 사용할 수 있습니다.
jobExecutionVetoed void 다른 JobListener가 Job의 실행을 방해(veto)했을 때 호출되는 메서드입니다.
jobWasExecuted void Job의 실행이 완료된 후에 호출되는 메서드로, Job의 실행 결과를 로깅하거나 후속 작업을 수행하는 데 사용할 수 있습니다.
package com.adjh.multiflexapi.scheduler.job;

import org.quartz.JobListener
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * Job의 생명주기를 관리합니다.
 *
 * @author : lee
 * @fileName : MyJobListener
 * @since : 2/28/24
 */
public class MyJobListener implements JobListener {
    @Override
    public String getName() {
        return "hello";
    }

    /**
     * Job 실행 이전 수행
     *
     * @param jobExecutionContext
     */
    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        System.out.println("[-] Job이 실행되기전 수행됩니다");
    }

    /**
     * Job 실행 취소 시점 수행
     *
     * @param jobExecutionContext
     */
    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
        System.out.println("[-] Job이 실행 취소된 시점 수행됩니다.");

    }

    /**
     * Job 실행 완료 시점 수행
     *
     * @param jobExecutionContext
     * @param e
     */
    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        System.out.println("[+] Job이 실행 완료된 시점 수행됩니다.");
    }
}

 

 

 

4. SchedulerConfig 구성


💡 SchedulerConfig 구성

- 해당 클래스에서는 스케줄러를 구성하는 과정을 정의한 클래스입니다. Job, Trigger, Scheduler 인스턴스를 생성하여 일정 시간마다 수행하도록 구성합니다.

- 아래의 예시에서는 트리거에서 10초마다 반복처리 되어 수행되도록 구성되어 있습니다.
메서드 설명
jobProgress 생성자 구성 및 초기 구성을 마치고 @PostConstruct 어노테이션에 따라 수행이 되며 스케줄러를 선택하여 호출하면 스케줄러가 수행이 되는 메서드입니다.
simpleScheduler SimpleScheduler를 이용하여서 스케줄러를 구성하는 메서드입니다.
cronScheduler CronScheduler를 이용하여 스케줄러를 구성하는 메서드입니다.
package com.adjh.multiflexapi.scheduler;

import com.adjh.multiflexapi.scheduler.job.MyJob;
import com.adjh.multiflexapi.scheduler.job.MyJobListener;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * 스케줄러의 설정을 관리합니다.
 *
 * @author : lee
 * @fileName : ScheduleConfig
 * @since : 2/28/24
 */
@Configuration
public class SchedulerConfig {

    private Scheduler scheduler;

    public SchedulerConfig(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    /**
     * 스케줄러의 실제 처리 과정을 담당합니다.
     */
    @PostConstruct
    private void jobProgress() throws SchedulerException {
        cronScheduler();
    }

    /**
     * SimpleScheduler 구성 메서드
     *
     * @throws SchedulerException
     */
    private void simpleScheduler() throws SchedulerException {
        // [STEP1] Job 생성
        JobDetail job = JobBuilder
                .newJob(MyJob.class)                                   // Job 구현 클래스
                .withIdentity("myJob", "myGroup")     // Job 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Job")   // Job 설명
                .build();

        // [STEP2] Trigger 생성
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "myGroup")         // Trigger 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Trigger")     // Trigger 설명
                .startNow()
                .withSchedule(
                        SimpleScheduleBuilder
                                .simpleSchedule()
                                .withIntervalInSeconds(5)
                                .repeatForever())
                .build();

        // [STEP3] 스케줄러 생성 및 Job, Trigger 등록
        scheduler = new StdSchedulerFactory().getScheduler();
        MyJobListener myJobListener = new MyJobListener();
        scheduler.getListenerManager().addJobListener(myJobListener);
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }

    /**
     * CronScheduler 구성 메서드
     */
    private void cronScheduler() throws SchedulerException {

        // [STEP1] Job 생성
        JobDetail job = JobBuilder
                .newJob(MyJob.class)                                   // Job 구현 클래스
                .withIdentity("myJob", "myGroup")     // Job 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Job")   // Job 설명
                .build();

        CronTrigger cronTrigger = TriggerBuilder
                .newTrigger()
                .withIdentity("fcmSendTrigger", "fcmGroup")         // Trigger 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Trigger")     // Trigger 설명
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")).build();

        // [STEP3] 스케줄러 생성 및 Job, Trigger 등록
        scheduler = new StdSchedulerFactory().getScheduler();
        MyJobListener myJobListener = new MyJobListener();
        scheduler.getListenerManager().addJobListener(myJobListener);
        scheduler.start();
        scheduler.scheduleJob(job, cronTrigger);
    }

}

 

 

6) 수행 과정


 

1. 서버 실행


💡 서버 실행

- 애플리케이션 서버가 실행되면 ‘Start Quartz Scheduler now’ 메시지가 출력되며 스케줄러가 수행됩니다.

 

 

 

2. JobListener 수행 : 콘솔 출력


💡 JobListener 수행 : 콘솔 출력

- Job이 실행하기 전, 후에 JobListener에서 수행이 됩니다.

 

 

 

3. Job 수행 : 콘솔 출력


💡 Job 수행 : 콘솔 출력

- Job이 수행이 되며 콘솔이 출력됩니다.

 

 

 

 

 

 

 

오늘도 감사합니다. 😀

 

 

 

 

반응형