본문 바로가기
IT/Java

Quartz 스케줄러 part.2

by 성준하이 2022. 10. 3.
반응형

저번 포스팅에 이어 코드를 다뤄볼 것이다.

 

일단 먼저 메인 함수를 작성할 jobexecutor를 만들어야한다.

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class SampleJobExecutor implements Job{


private static final SimpleDateFormat TIMESTAMP_FMT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSSS");
    public static final String EXECUTION_COUNT = "EXECUTION_COUNT";
    
    @Override
    public void execute(JobExecutionContext ctx) throws JobExecutionException {
        JobDataMap map = ctx.getJobDetail().getJobDataMap();
        String currentDate = TIMESTAMP_FMT.format(new Date());
        String message = map.getString("message");
 
        int executeCount = 0;
        if (map.containsKey(EXECUTION_COUNT)) {
            executeCount = map.getInt(EXECUTION_COUNT);
        }
        executeCount += 1;
        map.put(EXECUTION_COUNT, executeCount);
        
        System.out.println(String.format("[%-18s][%d][%s] %s", "execute", executeCount, currentDate, message ));
    }
}


/**
 * Quartz Scheduler 실행
 */
class JobLuacher {
    public static void main(String[] args) {
        try {
            // Scheduler 생성
            SchedulerFactory factory = new StdSchedulerFactory();
            Scheduler scheduler = factory.getScheduler();
            
            // Listener 설정
            ListenerManager listenrManager = scheduler.getListenerManager(); 
            listenrManager.addJobListener(new SampleJobListener());
            listenrManager.addTriggerListener(new SampleTriggerListener());
            
            // Scheduler 실행
            scheduler.start();
 
            // JOB Executor Class
            Class<? extends Job> jobClass = SampleJobExecutor.class;
            
            // JOB Data 객체 생성
            JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.put("message", "Hello, Quartz!!!");
            jobDataMap.put(SampleJobExecutor.EXECUTION_COUNT, 0);
 
            // JOB 생성
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
                                    .withIdentity("job_name", "job_group")
                                    .setJobData(jobDataMap)
                                    .build();
            
            // SimpleTrigger 생성
            // 5초마다 반복하며, 최대 10회 실행
            SimpleScheduleBuilder simpleSch = SimpleScheduleBuilder.simpleSchedule()
                                                .withRepeatCount(10)
                                                .withIntervalInSeconds(5);
            SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger()
                                            .withIdentity("simple_trigger", "simple_trigger_group")
                                            .withSchedule(simpleSch)
                                            .forJob(jobDetail)
                                            .build();
 
            // Schedule 등록
            scheduler.scheduleJob(jobDetail, simpleTrigger);
 
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

 

다음은 이어서 Listener 들이다.

implements를 상속받아 구현이 되어 쉽게 코드 작성이 가능하다.

public class SampleJobListener implements JobListener{


@Override
    public String getName() {
        return SampleJobListener.class.getName();
    }
 
    /**
     * Job이 수행되기 전 상태
     *   - TriggerListener.vetoJobExecution == false
     */
    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        System.out.println(String.format("[%-18s][%s] 작업시작", "jobToBeExecuted", context.getJobDetail().getKey().toString()));
    }
 
    /**
     * Job이 중단된 상태
     *   - TriggerListener.vetoJobExecution == true
     */
    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        System.out.println(String.format("[%-18s][%s] 작업중단", "jobExecutionVetoed", context.getJobDetail().getKey().toString()));
    }
 
    /**
     * Job 수행이 완료된 상태
     */
    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        System.out.println(String.format("[%-18s][%s] 작업완료", "jobWasExecuted", context.getJobDetail().getKey().toString()));
    }


}
public class SampleTriggerListener implements TriggerListener {


public static final String EXECUTION_COUNT = "EXECUTION_COUNT";

@Override
public String getName() {
// TODO Auto-generated method stub
return SampleTriggerListener.class.getName();
}


@Override
public void triggerFired(Trigger trigger, JobExecutionContext context) {
// TODO Auto-generated method stub
System.out.println(String.format("\n[%-18s][%s]", "triggerFired", trigger.getKey().toString()));

}


@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
// TODO Auto-generated method stub
JobDataMap map = context.getJobDetail().getJobDataMap();
        int executeCount = -1;
        if (map.containsKey(EXECUTION_COUNT)) {
            executeCount = map.getInt(EXECUTION_COUNT);
        }
        System.out.println(String.format("[%-18s][%s]", "vetoJobExecution", trigger.getKey().toString()));
        
        return executeCount >= 3;
}


@Override
public void triggerMisfired(Trigger trigger) {
// TODO Auto-generated method stub
System.out.println(String.format("[%-18s][%s]", "triggerMisfired", trigger.getKey().toString()));

}


@Override
public void triggerComplete(Trigger trigger, JobExecutionContext context,
CompletedExecutionInstruction triggerInstructionCode) {
// TODO Auto-generated method stub
System.out.println(String.format("[%-18s][%s]", "triggerComplete", trigger.getKey().toString()));

}


}

 

이렇게 작성한 후 메인 함수를 실행해보자.

 

execute의 연산이 이루어지면서 3이상이 될 경우엔 작업이 중지되는 로그를 확인할수 있을것이다.

 

사용법은 다양하여 이 코드를 수정 하여 로그를 작성해도 좋고 주기적인 패턴의 작업을 지정할수도 있을것이다.

반응형

'IT > Java' 카테고리의 다른 글

Maven 사용법  (55) 2022.10.05
HashTable, HashMap, ConcurrentHashMap 비교  (54) 2022.10.04
Quartz 스케줄러 part.1  (34) 2022.10.02
PSA 란?  (54) 2022.09.28
Assertions.assertThat 비교 하기  (40) 2022.09.24

댓글