はじめに
Springで定期実行をする場合は@Scheduledがお手軽に使えていいのですが、
後から時間の変更をする等の複雑な処理には対応していないようです。
そこでQuartzを導入しようとしたのですが情報が少なかったので備忘録として残します。
依存関係
- Lombok
- Spring Web
- Spring Data JPA
- Quartz Scheduler
設定
インメモリではなくデータベースを使用する。
application.properties
spring.quartz.job-store-type=jdbc
Quartz用の設定はquartz.propertiesを作成する。
もしくはapplication.propertiesに下記をつけ足して書く。
spring.quartz.properties.org.quartz.....
各コネクションプール用の設定
SQL
各データベース用のSQLを選んでimport.sqlに書く。
ジョブ
SimpleJob.class
@Slf4j
public class SimpleJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context){
log.info("SimpleJob Start");
//ジョブの処理
log.info("SimpleJob End");
}
}
サービスクラス
SchedulerService.class
@Slf4j
@RequiredArgsConstructor
@Service
public class SchedulerService {
@NonNull
private SchedulerFactoryBean schedulerFactoryBean;
@NonNull
private ApplicationContext context;
private final String name = "hoge";
private final String group = "fuga";
private final String cron = "*/10 * * * * * ?";//10秒ごとに実行
public void insert() {//作成
JobDetailFactoryBean jobDetailFB = new JobDetailFactoryBean();
jobDetailFB.setApplicationContext(context);
jobDetailFB.setJobClass(SimpleJob.class);
jobDetailFB.setName(name);
jobDetailFB.setGroup(group);//設定しない場合は自動的にDEFAULT_GROUPになる
JobDataMap jobDataMap = new JobDataMap();
//jobDataMap.put(key, value)でジョブへデータ受け渡し
jobDetailFB.setJobDataMap(jobDataMap);
jobDetailFB.afterPropertiesSet();
CronTriggerFactoryBean cronTriggerFB = new CronTriggerFactoryBean();
cronTriggerFB.setName(name);
cronTrigger.setGroup(group);//設定しない場合は自動的にDEFAULT_GROUPになる
cronTriggerFB.setStartTime(new Date());
cronTriggerFB.setCronExpression(cron);
cronTriggerFB.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
//SimpleTriggerクラスの定数を設定
try {
cronTriggerFB.afterPropertiesSet();
schedulerFactoryBean.getScheduler().scheduleJob(jobDetailFB.getObject(), cronTriggerFB.getObject());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
public void update() {//変更
CronTriggerFactoryBean cronTriggerFB = new CronTriggerFactoryBean();
cronTriggerFB.setName(name);
cronTrigger.setGroup(group);//設定しない場合は自動的にDEFAULT_GROUPになる
cronTriggerFB.setStartTime(new Date());
cronTriggerFB.setCronExpression(cron);
cronTriggerFB.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
//SimpleTriggerクラスの定数を設定
try {
cronTriggerFB.afterPropertiesSet();
schedulerFactoryBean.getScheduler().rescheduleJob(TriggerKey.triggerKey(name, group), cronTriggerFB.getObject());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
public void pause() {//停止
try {
schedulerFactoryBean.getScheduler().pauseJob(new JobKey(name, group));
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
}
}
public void resume() {//再開
try {
schedulerFactoryBean.getScheduler().resumeJob(new JobKey(name, group));
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
}
}
public void execute() {//一回のみ実行
try {
schedulerFactoryBean.getScheduler().triggerJob(new JobKey(name, group));
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
}
}
public void delete() {//削除
try {
schedulerFactoryBean.getScheduler().deleteJob(new JobKey(name, group));
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
}
}
}
まとめ
これでデータベースと連携させて複雑な定期実行も出来ると思います。
最新のSpringのリファレンスからQuartzが消えているのはどうしてなんだろう……。
参考