Quartz로 Spring에서 스케줄링

1. 개요

이 튜토리얼에서는 Quartz를 사용하여 Spring에서 간단한 Scheduler를 빌드 할 것 입니다.

새 예약 된 작업을 쉽게 구성하는 간단한 목표부터 시작하겠습니다.

1.1. Quartz API의 주요 구성 요소

Quartz는 모듈 식 아키텍처를 가지고 있습니다. 필요에 따라 결합 할 수있는 몇 가지 기본 구성 요소로 구성됩니다. 이 튜토리얼에서는 모든 작업에 공통적 인 Job , JobDetail , TriggerScheduler에 초점을 맞출 것입니다 .

애플리케이션을 관리하기 위해 Spring을 사용할 것이지만, 각각의 개별 컴포넌트는 Quartz 방식 또는 Spring 방식 (편의 클래스 사용)의 두 가지 방식으로 구성 할 수 있습니다 .

완전성을 위해 가능한 한 두 가지를 모두 다룰 것이지만 둘 중 하나를 채택 할 수도 있습니다. 한 번에 하나의 구성 요소를 구축해 보겠습니다.

2. 작업 하고 있는 JobDetail

2.1.

API는 실행이라는 하나의 메소드 만 있는 작업 인터페이스를 제공합니다 . 수행 할 실제 작업, 즉 작업을 포함하는 클래스에 의해 구현되어야합니다. 작업의 트리거가 실행 되면 스케줄러는 execute 메서드를 호출하여 JobExecutionContext 개체에 전달 합니다.

JobExecutionContext를이 스케줄러에 대한 핸들, 트리거에 대한 핸들, 그리고 작업의를 포함하여 런타임 환경에 대한 정보와 함께 작업 인스턴스를 제공 하기 JobDetail 객체입니다.

이 빠른 예에서 작업은 작업을 서비스 클래스에 위임합니다.

@Component public class SampleJob implements Job { @Autowired private SampleJobService jobService; public void execute(JobExecutionContext context) throws JobExecutionException { jobService.executeSampleJob(); } } 

2.2. JobDetail

작업이 일꾼이지만 Quartz는 작업 클래스의 실제 인스턴스를 저장하지 않습니다. 대신 JobDetail 클래스를 사용하여 Job 의 인스턴스를 정의 할 수 있습니다 . 실행할 작업 의 유형 을 알 수 있도록 작업의 클래스를 JobDetail에 제공해야합니다 .

2.3. Quartz JobBuilder

Quartz JobBuilderJobDetail 엔티티 를 구성하기위한 빌더 스타일 API를 제공합니다 .

@Bean public JobDetail jobDetail() { return JobBuilder.newJob().ofType(SampleJob.class) .storeDurably() .withIdentity("Qrtz_Job_Detail") .withDescription("Invoke Sample Job service...") .build(); }

2.4. 스프링 JobDetailFactoryBean

Spring의 JobDetailFactoryBeanJobDetail 인스턴스 를 구성하기 위해 빈 스타일의 사용을 제공 합니다. 달리 지정되지 않은 경우 Spring Bean 이름을 작업 이름으로 사용합니다.

@Bean public JobDetailFactoryBean jobDetail() { JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); jobDetailFactory.setJobClass(SampleJob.class); jobDetailFactory.setDescription("Invoke Sample Job service..."); jobDetailFactory.setDurability(true); return jobDetailFactory; }

작업이 실행될 때마다 JobDetail 의 새 인스턴스 가 생성됩니다. 만약 JobDetail은 객체 전달하는 작업의 세부 속성을. 실행이 완료되면 인스턴스에 대한 참조가 삭제됩니다.

3. 트리거

트리거는 일정에 메커니즘입니다 작업 , 즉 트리거 예 "화재"작업의 실행을. 작업 ( 작업 개념)과 트리거 (일정 메커니즘) 간에 책임이 명확하게 구분 됩니다.

Job 외에도 트리거 에는 예약 요구 사항에 따라 선택할 수 있는 유형 이 필요합니다 .

한 시간에 한 번씩, 무기한 으로 실행되도록 작업을 예약하고 싶다고 가정 해 보겠습니다. Quartz의 TriggerBuilder 또는 Spring의 SimpleTriggerFactoryBean 을 사용할 수 있습니다 .

3.1. 석영 TriggerBuilder

TriggerBuilderTrigger 엔티티 를 구성하기위한 빌더 스타일 API입니다 .

@Bean public Trigger trigger(JobDetail job) { return TriggerBuilder.newTrigger().forJob(job) .withIdentity("Qrtz_Trigger") .withDescription("Sample trigger") .withSchedule(simpleSchedule().repeatForever().withIntervalInHours(1)) .build(); }

3.2. 스프링 SimpleTriggerFactoryBean

SimpleTriggerFactoryBean는 구성을위한 콩 스타일의 사용을 제공 SimpleTrigger를 . 스프링 빈 이름을 트리거 이름으로 사용하고 별도로 지정하지 않으면 무한 반복으로 기본 설정됩니다.

@Bean public SimpleTriggerFactoryBean trigger(JobDetail job) { SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); trigger.setJobDetail(job); trigger.setRepeatInterval(3600000); trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); return trigger; }

4. JobStore 구성

JobStoreJobTrigger에 대한 저장 메커니즘을 제공하며 작업 스케줄러와 관련된 모든 데이터를 유지 관리합니다. API는 인 메모리영구 저장소를 모두 지원합니다 .

4.1. 메모리 내 JobStore

예를 목적으로, 우리는 메모리 사용 RAMJobStore 이벤트 타오르는 빠른 통해 성능과 간단한 구성 quartz.properties를 :

org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore

RAMJobStore 의 명백한 단점은 본질적 으로 휘발성 이라는 것입니다 . 모든 일정 정보는 종료 사이에 손실됩니다. 종료 사이에 작업 정의 및 일정을 유지해야하는 경우 영구 JDBCJobStore 를 대신 사용해야합니다.

인 - 메모리 사용하려면 JobStore 봄을 , 우리는 우리의이 속성 설정 application.properties를 :

spring.quartz.job-store-type=memory

4.2. JDBC 작업 저장소

JDBCJobStore 에는 JobStoreTXJobStoreCMT 의 두 가지 유형이 있습니다 . 둘 다 데이터베이스에 스케줄링 정보를 저장하는 동일한 작업을 수행합니다.

둘의 차이점은 데이터를 커밋하는 트랜잭션을 관리하는 방법입니다. JobStoreCMT의 유형은 반면에 데이터를 저장하는 응용 프로그램 트랜잭션이 필요 JobStoreTX의 종류가 시작하고 자신의 트랜잭션을 관리합니다.

JDBCJobStore에 대해 설정할 몇 가지 속성이 있습니다 . 최소한 JDBCJobStore 유형 , 데이터 소스 및 데이터베이스 드라이버 클래스를 지정해야합니다 . 대부분의 데이터베이스에 대한 드라이버 클래스가 있지만 StdJDBCDelegate 는 대부분의 경우를 다룹니다.

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.dataSource=quartzDataSource

Spring에서 JDBC JobStore 를 설정하려면 몇 단계를 거쳐야합니다. 먼저 application.properties 에서 저장소 유형을 설정합니다 .

spring.quartz.job-store-type=jdbc

다음으로 자동 구성을 활성화하고 Quartz 스케줄러에 필요한 데이터 소스를 Spring에 제공해야합니다. @QuartzDataSource의 주석 구성 및 우리를 위해 석영 데이터베이스를 초기화하는 어려운 작업을 수행합니다

@Configuration @EnableAutoConfiguration public class SpringQrtzScheduler { @Bean @QuartzDataSource public DataSource quartzDataSource() { return DataSourceBuilder.create().build(); } }

5. 스케줄러

스케줄러 인터페이스는 작업 스케줄러와 인터페이스의 주요 API입니다.

스케줄러는 인스턴스화 할 수 SchedulerFactory. 생성 된 작업트리거 는 여기에 등록 할 수 있습니다. 처음에 스케줄러 는 "대기"모드에 있으며 작업 실행을 시작하는 스레드를 시작하려면 시작 메소드를 호출해야합니다.

5.1. Quartz StdSchedulerFactory

단순히 호출하여 getScheduler의 온 방법을 StdSchedulerFactory , 우리는 인스턴스화 할 수 스케줄러 (구성된으로 초기화 JobStoreThreadPool이 ), 그 API에 대한 핸들을 반환 :

@Bean public Scheduler scheduler(Trigger trigger, JobDetail job, SchedulerFactoryBean factory) throws SchedulerException { Scheduler scheduler = factory.getScheduler(); scheduler.scheduleJob(job, trigger); scheduler.start(); return scheduler; }

5.2. Spring SchedulerFactoryBean

봄의 의 SchedulerFactoryBean은 구성하는 콩 스타일의 사용을 제공 스케줄러 , 애플리케이션 컨텍스트 내 라이프 사이클을 관리하고, 노출 스케줄러를 의존성 주입을위한 빈으로 :

@Bean public SchedulerFactoryBean scheduler(Trigger trigger, JobDetail job, DataSource quartzDataSource) { SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean(); schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties")); schedulerFactory.setJobFactory(springBeanJobFactory()); schedulerFactory.setJobDetails(job); schedulerFactory.setTriggers(trigger); schedulerFactory.setDataSource(quartzDataSource); return schedulerFactory; }

5.3. SpringBeanJobFactory 구성

SpringBeanJobFactory은 인스턴스를 만드는 동안 작업 콩에 속성으로 스케줄러 상황, 작업 데이터지도 및 트리거 데이터 항목을 주입하기위한 지원을 제공합니다.

그러나 애플리케이션 컨텍스트 에서 빈 참조를 삽입하는 데 대한 지원이 부족합니다 . 이 블로그 게시물의 작성자 덕분에 다음 과 같이 SpringBeanJobFactory에 자동 연결 지원을 추가 할 수 있습니다 .

@Bean public SpringBeanJobFactory springBeanJobFactory() { AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); return jobFactory; }

6. 결론

That's all. We have just built our first basic scheduler using the Quartz API as well as Spring's convenience classes.

The key takeaway from this tutorial is that we were able to configure a job with just a few lines of code and without using any XML-based configuration.

The complete source code for the example is available in this github project. It is a Maven project which can be imported and run as-is. The default setting uses Spring's convenience classes, which can be easily switched to Quartz API with a run-time parameter (refer to the README.md in the repository).