Quartzを使った春のスケジューリング

Quartzを使用した春のスケジューリング

1. 概要

このチュートリアルでは、単純なScheduler in Spring with Quartzを作成します。

まず、新しいスケジュールされたジョブを簡単に構成するという単純な目標を念頭に置いて開始します。

1.1. QuartzAPIの主要コンポーネント

Quartzにはモジュラーアーキテクチャがあります。 必要に応じて組み合わせることができるいくつかの基本的なコンポーネントで構成されています。 このチュートリアルでは、すべてのジョブに共通するもの、つまりJobJobDetailTrigger、およびSchedulerに焦点を当てます。

Springを使用してアプリケーションを管理しますが、個々のコンポーネントは、Quartz方法またはSpring方法(コンビニエンスクラスを使用)の2つの方法で構成できます。

完全を期すため、可能な限り両方をカバーしますが、どちらを採用してもかまいません。 一度に1つのコンポーネントの構築を始めましょう。

参考文献:

Spring Task Schedulerのガイド

タスクスケジューラを使用したSpringでのスケジューリングの迅速かつ実用的なガイド

Java EEでのスケジューリング

@Scheduleアノテーションとタイマーサービスを使用してJava EEでタスクをスケジュールする方法のデモ。

Droolsの概要

Droolsをビジネスルール管理システム(BRMS)として使用する方法を学びます。

2. JobおよびJobDetail

2.1. Job

APIは、execute.という1つのメソッドのみを持つJobインターフェイスを提供します。これは、実行する実際の作業を含むクラスによって実装する必要があります。 タスク。 ジョブのトリガーが起動すると、スケジューラーは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に提供して、実行するジョブのtypeを認識できるようにする必要があります。

2.3. クォーツJobBuilder

QuartzJobBuilderは、JobDetailエンティティ.を構築するためのビルダースタイルの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のJobDetailFactoryBeanは、JobDetailインスタンスを構成するためのBeanスタイルの使用法を提供します。 特に指定しない限り、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. 引き金

Triggerは、Jobをスケジュールするメカニズムです。 Triggerインスタンスは、ジョブの実行を「起動」します。 Job(タスクの概念)とTrigger(スケジューリングメカニズム)の間には、責任が明確に分離されています。

Jobに加えて、トリガーには、スケジューリング要件に基づいて選択できるtypeも必要です。

たとえば、once every hour,を無期限に実行するようにタスクをスケジュールしたいとします。QuartzのTriggerBuilderまたはSpringのSimpleTriggerFactoryBeanを使用して実行できます。

3.1. クォーツTriggerBuilder

TriggerBuilderは、Triggerエンティティを構築するためのビルダースタイルの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スタイルの使用法を提供します。 Spring Bean名をトリガー名として使用し、特に指定がない場合はデフォルトで無期限の繰り返しになります。

@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の構成

JobStoreは、JobおよびTriggerのストレージメカニズムを提供し、ジョブスケジューラに関連するすべてのデータを維持する責任があります。 APIは、in-memoryストアとpersistentストアの両方をサポートします。

4.1. インメモリJobStore

例として、quartz.propertiesを介して超高速のパフォーマンスと簡単な構成を提供するメモリ内のRAMJobStoreを使用します。

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

RAMJobStoreの明らかな欠点は、本質的にvolatileであるということです。 すべてのスケジューリング情報は、シャットダウンの間に失われます。 ジョブの定義とスケジュールをシャットダウンの間に保持する必要がある場合は、代わりに永続的なJDBCJobStoreを使用する必要があります。 Spring,でメモリ内のJobStoreを有効にするには、application.propertiesでこのプロパティを設定します。

spring.quartz.job-store-type=memory

4.2. JDBCJobStore

JDBCJobStoreには、JobStoreTXJobStoreCMTの2種類があります。 どちらも、データベースにスケジュール情報を保存するという同じ仕事をします。

2つの違いは、データをコミットするトランザクションの管理方法です。 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でJDBCJobStoreを設定するには、いくつかの手順が必要です。 まず、application.propertiesにストアタイプを設定します。

spring.quartz.job-store-type=jdbc

次に、自動構成を有効にして、SpringにQuartzスケジューラーに必要なデータソースを提供する必要があります。 @QuartzDataSourceアノテーションは、Quartzデータベースの構成と初期化に大変な作業を行います。

@Configuration
@EnableAutoConfiguration
public class SpringQrtzScheduler {

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

5. Scheduler

Schedulerインターフェースは、ジョブスケジューラとインターフェースするためのメインAPIです。

SchedulerSchedulerFactory.でインスタンス化できます。作成したら、JobsとTriggersを登録できます。 最初、Schedulerは「スタンバイ」モードであり、ジョブの実行を開始するスレッドを開始するには、そのstartメソッドを呼び出す必要があります。

5.1. クォーツStdSchedulerFactory

StdSchedulerFactorygetSchedulerメソッドを呼び出すだけで、Schedulerをインスタンス化し、(構成された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. 春SchedulerFactoryBean

SpringのSchedulerFactoryBeanは、Schedulerを構成するためのBeanスタイルの使用法を提供し、アプリケーションコンテキスト内でそのライフサイクルを管理し、依存性注入用のBeanとしてSchedulerを公開します。

@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は、インスタンスの作成中に、スケジューラコンテキスト、ジョブデータマップ、およびトリガーデータエントリをプロパティとしてジョブBeanに挿入するためのサポートを提供します。

ただし、application contextからBean参照を挿入するためのサポートはありません。 this blog postの作成者のおかげで、次のようにauto-wiringサポートをSpringBeanJobFactoryに追加できます。

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

6. 結論

それで全部です。 QuartzAPIとSpringのコンビニエンスクラスを使用して最初の基本的なスケジューラーを構築しました。

このチュートリアルの重要なポイントは、XMLベースの構成を使用せずに、わずか数行のコードでジョブを構成できたことです。

この例の完全なsource codeは、this github projectで利用できます。 これは、インポートしてそのまま実行できるMavenプロジェクトです。 デフォルト設定では、Springのコンビニエンスクラスを使用します。これは、ランタイムパラメータを使用してQuartz APIに簡単に切り替えることができます(リポジトリのREADME.mdを参照)。