石英の紹介

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に載っています]。