1. 概要

このチュートリアルでは、Quartzを使用してSpringで単純なスケジューラーを構築します。

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

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

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

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

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

2. ジョブおよびジョブ詳細

2.1. ジョブ

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のインスタンスを定義できます。 実行するジョブのtypeを認識できるように、ジョブのクラスをJobDetailに提供する必要があります。

2.3. クォーツJobBuilder

Quartz JobBuilder は、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. Spring JobDetailFactoryBean

SpringのJobDetailFactoryBean は、JobDetailインスタンスを構成するためのbeanスタイルの使用法を提供します。 特に指定がない限り、SpringBean名をジョブ名として使用します。

@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. 引き金

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

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

たとえば、を1時間に1回、を無期限に実行するようにタスクをスケジュールしたいとします。これには、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. Spring SimpleTriggerFactoryBean

SimpleTriggerFactoryBean は、SimpleTriggerを構成するためのBeanスタイルの使用法を提供します。 トリガー名としてSpringBean名を使用し、特に指定がない限り、デフォルトで無期限の繰り返しになります。

@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は、メモリ内ストアと永続ストアの両方をサポートします。

4.1. インメモリJobStore

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

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

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

spring.quartz.job-store-type=memory

4.2. JDBC JobStore

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

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

@Configuration
@EnableAutoConfiguration
public class SpringQrtzScheduler {

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

5. スケジューラー

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

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

5.1. クォーツStdSchedulerFactory

StdSchedulerFactorygetSchedulerメソッドを呼び出すだけで、 Scheduler をインスタンス化し、初期化できます(構成済みの JobStoreおよびを使用) ] ThreadPool )、そしてその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

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

@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に挿入するためのサポートを提供します。

ただし、アプリケーションコンテキストからのBean参照の挿入はサポートされていません。 このブログ投稿の作成者のおかげで、自動配線サポートをSpringBeanJobFactoryに次のように追加できます。

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

6. 結論

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

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

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