1概要


  • Quartz

    ** は完全にJavaで書かれた

    J2SE



    J2EE

    の両方のアプリケーションで使用するために設計されたオープンソースのジョブスケジューリングフレームワークです。シンプルさを犠牲にすることなく、大きな柔軟性を提供します。

ジョブを実行するための複雑なスケジュールを作成できます。例は、例えばである。毎日、毎週金曜日の午後7時30分に実行されるタスク。または毎月の最終日にのみ。

この記事では、Quartz APIを使用して仕事を構築するための要素について説明します。 Springと組み合わせて導入するには、

Spring with Quartzでのスケジューリング

をお勧めします。


2 Mavenの依存関係

__pom.xmlに次の依存関係を追加する必要があります。

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

最新版はhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.quartz-scheduler%22%20AND%20a%3A%22quartz%22[Mavenにあります中央リポジトリ]。


3 Quartz API

フレームワークの中心は

Scheduler

です。それは私たちのアプリケーションのためのランタイム環境を管理する責任があります。

スケーラビリティを確保するために、Quartzはマルチスレッドアーキテクチャに基づいています。

  • 開始されると、フレームワークは

    Scheduler



    Jobs

    を実行するために使用する** 一連のワーカースレッドを初期化します。

これが、フレームワークが多数の

Jobs

を同時に実行できる方法です。スレッド環境を管理するための

ThreadPool

管理コンポーネントの疎結合セットにも依存します。

APIの主なインタフェースは次のとおりです。


  • Scheduler –

    のスケジューラと対話するための主要なAPI

枠組み
**

Job –

コンポーネントが実装したいインターフェイス

実行した
**

JobDetail –


__Job

__のインスタンスを定義するために使用


  • Trigger –

    スケジュールを決定するコンポーネント。

与えられた

Job

が実行されます
**

JobBuilder –

は、以下を定義する

JobDetail

インスタンスを構築するために使用されます。


Jobs

のインスタンス
**

TriggerBuilder –



Trigger

インスタンスを構築するために使用されます

これらのコンポーネントのそれぞれについて見てみましょう。


4スケジューラ


Scheduler

を使用する前に、インスタンス化する必要があります。これを行うには、ファクトリー

SchedulerFactory


:



を使用できます。

SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();


Scheduler

のライフサイクルは、

SchedulerFactory

とその

shutdown()

メソッドの呼び出しによって作成されます。

Scheduler

インタフェースを作成すると、

Jobs



Triggers

を追加、削除、一覧表示したり、その他のスケジューリング関連の操作(トリガの一時停止など)を実行したりすることができます。

しかし、

Scheduler



start()

メソッドで起動されるまで、どのトリガに対しても作用しません

scheduler.start();


5仕事


Job

は、

Job

インターフェースを実装するクラスです。それはただ一つの簡単な方法を持っています:

public class SimpleJob implements Job {
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("This is a quartz job!");
    }
}


Job’s

トリガーが起動すると、

execute()

メソッドがスケジューラのワーカースレッドの1つによって呼び出されます。

このメソッドに渡される

JobExecutionContext

オブジェクトは、実行時環境に関する情報、それを実行した

Scheduler

へのハンドル、実行をトリガーした

Trigger

へのハンドル、およびジョブの

JobDetail

オブジェクトなどの情報をジョブインスタンスに提供します。 。


JobDetail

オブジェクトは、

Job



Schedulerに追加されたときにQuartzクライアントによって作成されます。これは、基本的にジョブインスタンスの定義です


:

__

JobDetail job = JobBuilder.newJob(SimpleJob.class)
  .withIdentity("myJob", "group1")
  .build();

このオブジェクトには、

Job

のさまざまなプロパティ設定、および

JobDataMap

を含めることもできます。これは、ジョブクラスの特定のインスタンスの状態情報を格納するために使用できます。


5.1.

JobDataMap



JobDataMap

は、実行時にジョブインスタンスが利用できるようにしたい任意の量のデータオブジェクトを保持するために使用されます。

JobDataMap

は、Javaの

Map

インターフェースの実装であり、プリミティブ型のデータを格納および取得するための便利なメソッドがいくつか追加されています。

ジョブをスケジューラに追加する前に、

JobDetail

を構築しながら

JobDataMap

にデータを入れる例を示します。

JobDetail job = newJob(SimpleJob.class)
  .withIdentity("myJob", "group1")
  .usingJobData("jobSays", "Hello World!")
  .usingJobData("myFloatValue", 3.141f)
  .build();

これが、ジョブの実行中にこれらのデータにアクセスする方法の例です。

public class SimpleJob implements Job {
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();

        String jobSays = dataMap.getString("jobSays");
        float myFloatValue = dataMap.getFloat("myFloatValue");

        System.out.println("Job says: " + jobSays + ", and val is: " + myFloatValue);
    }
}

上記の例では、「JobからHello World!と言われ、valは3.141」と出力されます。

__JobDataMapのキーの名前に対応するセッターメソッドをジョブクラスに追加することもできます。

これを行うと、Quartzのデフォルトの

JobFactory

実装は、ジョブがインスタンス化されるときにそれらのセッターを自動的に呼び出すので、executeメソッド内でマップから値を明示的に取得する必要がなくなります。


6. トリガー


Trigger

オブジェクトは、

Jobs

の実行をトリガーするために使用されます。


Job

をスケジュールしたい場合は、トリガーをインスタンス化し、そのプロパティを調整してスケジューリング要件を設定する必要があります。

Trigger trigger = TriggerBuilder.newTrigger()
  .withIdentity("myTrigger", "group1")
  .startNow()
  .withSchedule(SimpleScheduleBuilder.simpleSchedule()
    .withIntervalInSeconds(40)
    .repeatForever())
  .build();


Trigger

には

JobDataMap

が関連付けられている場合もあります。これは、トリガーの実行に固有のパラメータを

Job

に渡すのに役立ちます。

さまざまなスケジューリングニーズに対してさまざまなタイプのトリガーがあります。

それぞれのIDを追跡するための

TriggerKey

プロパティが異なります。ただし、他のいくつかのプロパティはすべてのトリガタイプに共通です。


  • jobKey

    プロパティは、実行する必要があるジョブのIDを示します。

トリガーが起動したときに実行されます。


  • startTime

    プロパティは、トリガーのスケジュールが最初になる時刻を示します

発効する。値は

java.util.Date

オブジェクトです。これは、指定されたカレンダー日付の時刻を定義します。トリガーの種類によっては、トリガーは指定された開始時間に起動します。他の人にとっては、それは単にスケジュールが開始されるべき時を示します。


  • endTime

    プロパティは、トリガーのスケジュールをいつにするかを示します。

キャンセル。

Quartzにはいくつかの異なるトリガータイプが同梱されていますが、

最も一般的に使用されるものは

SimpleTrigger



CronTrigger


です。


6.1. 優先度

時々、私たちが多くのトリガーを持っているとき、Quartzはすぐに起動するのに十分なリソースを持っていないかもしれませんが同時に起動するようにスケジュールされています。この場合、どのトリガーが最初に利用可能になるかを制御したいと思うかもしれません。これはまさにトリガーの

priority

プロパティが使用されているものです。

  • たとえば** 10個のトリガーが同時に起動するように設定されていて、4つのワーカースレッドしか使用できない場合、最も優先順位の高い最初の4つのトリガーが最初に実行されます。トリガーに優先順位を設定しないと、デフォルトの優先順位5が使用されます。優先順位として、正または負の整数値を使用できます。

以下の例では、優先度が異なる2つのトリガーがあります。すべてのトリガーを同時に発動させるのに十分なリソースがない場合、

triggerA

が最初に発動するものになります。

Trigger triggerA = TriggerBuilder.newTrigger()
  .withIdentity("triggerA", "group1")
  .startNow()
  .withPriority(15)
  .withSchedule(SimpleScheduleBuilder.simpleSchedule()
    .withIntervalInSeconds(40)
    .repeatForever())
  .build();

Trigger triggerB = TriggerBuilder.newTrigger()
  .withIdentity("triggerB", "group1")
  .startNow()
  .withPriority(10)
  .withSchedule(SimpleScheduleBuilder.simpleSchedule()
    .withIntervalInSeconds(20)
    .repeatForever())
  .build();


6.2. 失火の指示


  • Scheduler

    がシャットダウンされているため、またはQuartzのスレッドプールに使用可能なスレッドがない場合に、永続的なトリガが起動時間を喪失すると** 失火が発生します。

トリガーの種類が異なれば、失火の指示も異なります。デフォルトでは、スマートポリシー命令を使用します。スケジューラは起動時に、発火した永続的なトリガを検索します。その後、それは彼らの個々に設定された失火の指示に基づいてそれらのそれぞれを更新します。

以下の例を見てみましょう。

Trigger misFiredTriggerA = TriggerBuilder.newTrigger()
  .startAt(DateUtils.addSeconds(new Date(), -10))
  .build();

Trigger misFiredTriggerB = TriggerBuilder.newTrigger()
  .startAt(DateUtils.addSeconds(new Date(), -10))
  .withSchedule(SimpleScheduleBuilder.simpleSchedule()
    .withMisfireHandlingInstructionFireNow())
  .build();

私たちは10秒前にトリガーを実行するようにスケジュールしました(それでそれはそれが作成される時までに10秒遅れます)。スケジューラが停止しているか、十分な量のワーカスレッドを利用できないためです。もちろん、現実のシナリオでは、このようなトリガーをスケジュールすることは決してありません。

最初のトリガー(

misFiredTriggerA

)では、失火処理命令は設定されていません。したがって、その場合は

smart policy

という呼び出しが使用され、__withMisfireHandlingInstructionFireNow()と呼ばれます。これは、スケジューラが失火を検出した直後にジョブが実行されることを意味します。

2番目のトリガーは、失火が発生したときに予想される動作の種類を明示的に定義します。この例では、たまたま同じスマートポリシーです。


6.3.

SimpleTrigger



  • SimpleTrigger

    は、特定の瞬間にジョブを実行する必要があるシナリオに使用されます。

例としては、2018年1月13日の午前12時20分00秒にジョブを実行することが考えられます。

以下のコードでは、日付

myStartTime

が以前に定義されており、特定のタイムスタンプ


:


のトリガーを構築するために使用されています

SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
  .withIdentity("trigger1", "group1")
  .startAt(myStartTime)
  .forJob("job1", "group1")
  .build();

次に、特定の瞬間にトリガーを作成し、10秒ごとに10回繰り返します。

SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
  .withIdentity("trigger2", "group1")
  .startAt(myStartTime)
  .withSchedule(simpleSchedule()
    .withIntervalInSeconds(10)
    .withRepeatCount(10))
  .forJob("job1")
  .build();


6.4.

CronTrigger



  • CronTrigger

    は、カレンダーのようなステートメントに基づくスケジュールが必要な場合に使用されます** たとえば、__金曜日の毎週金曜日、または午前9時30分の毎週日曜日のような起動スケジュールを指定できます。

Cron式は、

CronTrigger

のインスタンスを構成するために使用されます。これらの式は7つの部分式で構成される

Strings

で構成されています。 Cron式https://docs.oracle.com/cd/E12058

01/doc/doc.1014/e12030/cron

expressions.htm[ここ]について詳しく読むことができます。

以下の例では、毎日午前8時から午後5時の間に1分おきに発生するトリガーを作成します。

CronTrigger trigger = TriggerBuilder.newTrigger()
  .withIdentity("trigger3", "group1")
  .withSchedule(CronScheduleBuilder.cronSchedule("0 0/2 8-17 **  **  ?"))
  .forJob("myJob", "group1")
  .build();


7. 結論

この記事では、

Job

をトリガーする

Scheduler

の作成方法を示しました。私達はまた使用される最も一般的な制動機の選択のいくつかを見ました:


SimpleTrigger



CronTrigger

Quartzは、数十、数百、さらにはそれ以上のジョブを実行するための単純または複雑なスケジュールを作成するために使用できます。フレームワークの詳細については、メインのhttp://www.quartz-scheduler.org/[Webサイト]を参照してください。

例のソースコードはhttps://github.com/eugenp/tutorials/tree/master/libraries/src/main/java/com/baeldung/quartz[GitHubに載っています]。