QuartzとSpring Boot統合の基本概念
Quartzの主要コンポーネントはSchedulerがTriggerに基づきJobタスクを実行します。Spring Boot統合の核心は、QuartzジョブがSpring管理下で依存性注入を可能にすることです。
基本設定
QuartzのJobインスタンス生成をSpringが管理できるよう設定します。以下のクラスはQuartzの設定をネイティブプロパティファイルで管理します。
Quartz設定クラス
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import java.util.Properties;
@Configuration
public class QuartzConfig {
@Bean
public JobFactory customJobFactory(ApplicationContext context) {
SpringManagedJobFactory factory = new SpringManagedJobFactory();
factory.setAppContext(context);
return factory;
}
@Bean
public SchedulerFactoryBean schedulerFactory(JobFactory jobFactory) {
SchedulerFactoryBean schedulerBean = new SchedulerFactoryBean();
schedulerBean.setJobFactory(jobFactory);
schedulerBean.setQuartzProperties(quartzConfig());
return schedulerBean;
}
@Bean
public Properties quartzConfig() {
PropertiesFactoryBean propFactory = new PropertiesFactoryBean();
propFactory.setLocation(new ClassPathResource("/quartz.properties"));
return propFactory.getObject();
}
}
Spring管理Jobファクトリ
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
public class SpringManagedJobFactory extends SpringBeanJobFactory {
private AutowireCapableBeanFactory beanContainer;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object job = super.createJobInstance(bundle);
beanContainer.autowireBean(job);
return job;
}
public void setAppContext(ApplicationContext context) {
beanContainer = context.getAutowireCapableBeanFactory();
}
}
タスク設定と初期化
Job実装とスケジューラ初期化を行います。複数タスクを個別クラスで管理可能です。
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Calendar;
@Service
public class TaskSchedulerConfig {
@Autowired
private Scheduler quartzScheduler;
@Value("${task.image.capture.cron}")
private String imageCaptureCron;
@Value("${task.image.cleanup.cron}")
private String imageCleanupCron;
@PostConstruct
public void initializeTasks() {
setupImageCapture();
setupImageCleanup();
}
private void setupImageCapture() {
JobDetail job = JobBuilder.newJob(ImageCaptureJob.class)
.withIdentity("imageCapture", "imageTasks")
.build();
CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(imageCaptureCron)
.withMisfireHandlingInstructionDoNothing();
Calendar startTime = Calendar.getInstance();
startTime.set(Calendar.MINUTE, 0);
startTime.set(Calendar.SECOND, 0);
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("imageCaptureTrigger", "imageTasks")
.startAt(startTime.getTime())
.withSchedule(cron)
.build();
try {
quartzScheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
private void setupImageCleanup() {
JobDetail job = JobBuilder.newJob(ImageCleanupJob.class)
.withIdentity("imageCleanup", "imageTasks")
.build();
CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(imageCleanupCron)
.withMisfireHandlingInstructionDoNothing();
Calendar startTime = Calendar.getInstance();
startTime.set(Calendar.MINUTE, 0);
startTime.set(Calendar.SECOND, 0);
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("imageCleanupTrigger", "imageTasks")
.startAt(startTime.getTime())
.withSchedule(cron)
.build();
try {
quartzScheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}