JavaのQuartzライブラリのJobListenerで定義したジョブを監視する方法
org.quartz.JobListenerインタフェースをimplementsしたリスナークラスを作成してSchedulerのgetListenerManager().addJobListener()メソッドにリスナーのインスタンスを指定すると、ジョブを監視することができます。
オーバーライドするメソッドが4つあります。
| メソッド | 処理 |
|---|---|
| getName | 名前を返す |
| jobToBeExecuted | job実行前処理 |
| jobExecutionVetoed | 不明 |
| jobWasExecuted | job実行後処理 |
以下、Jobを監視するリスナークラスです。
package jp.co.confrage;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class AListener implements org.quartz.JobListener {
@Override
public String getName() {
return "default";
}
@Override
public void jobToBeExecuted(final JobExecutionContext context) {
System.out.println("処理前に呼ばれる");
}
@Override
public void jobExecutionVetoed(final JobExecutionContext context) {
System.out.println("ジョブ実行拒否されたら呼ばれる");
}
@Override
public void jobWasExecuted(
final JobExecutionContext context, final JobExecutionException jobException) {
System.out.println("処理後に呼ばれる");
}
}
とりあえずジョブの実行前後で標準出力するだけのリスナーを作成しました。リスナーAとします。
スケジューラにリスナーを登録する
2つのジョブAとジョブBを作成して、適当なトリガーでジョブBをスケジューリングします。
SchedulerクラスのgetListenerManager().addJobListener()メソッドにリスナーAのインスタンスを渡してリスナーを登録します。
| 第一引数 |
|---|
| JobListenerのインスタンス |
以下のようにリスナーを登録します。
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.getListenerManager().addJobListener(new AListener());
全ソースは以下です。
package jp.co.confrage;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class Library {
public static void main(final String[] args) {
JobKey keyA = new JobKey("job1", "group1");
JobKey keyB = new JobKey("job2", "group2");
JobDetail jobA = JobBuilder.newJob(AJob.class).withIdentity(keyA).build(); // 未使用
JobDetail jobB = JobBuilder.newJob(BJob.class).withIdentity(keyB).build();
Trigger trigger =
TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group2")
.startNow()
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(1000) // 1秒間隔
.repeatForever()) // 処理をずっと繰り返す
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getListenerManager().addJobListener(new AListener()); // AListenerを登録
scheduler.scheduleJob(jobB, trigger); // job Bをスケジューリング
scheduler.start(); // スタート
Thread.sleep(10000); // 10秒スリープ
scheduler.shutdown(); // エンド
} catch (SchedulerException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
この時、ジョブBに対してリスナーAが動作します。実行結果です。
処理前に呼ばれる BJob execute. 処理後に呼ばれる 処理前に呼ばれる BJob execute. 処理後に呼ばれる ...省略
ジョブAをスケジューリングしてもリスナーAが動作します。
org.quartz.impl.matchers.KeyMatcherクラスで識別子が一致する場合に監視する
リスナーAはジョブAだけを監視したい、ジョブBは監視させたくないといった場合、getListenerManager().addJobListener()メソッドの第二引数を追加します。
第一引数にリスナーAのインスタンスを指定します。
第二引数にMatcher<JobKey>を指定します。
| 第一引数 | 第二引数 |
|---|---|
| JobListenerのインスタンス | Matcher<JobKey> |
具体的には以下のような感じです。
JobKey keyA = new JobKey("job1", "group1");
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler
.getListenerManager()
.addJobListener(new AListener(), KeyMatcher.keyEquals(keyA)); // AListenerを登録
全ソースは以下です。
package jp.co.confrage;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.KeyMatcher;
public class Library {
public static void main(final String[] args) {
JobKey keyA = new JobKey("job1", "group1");
JobKey keyB = new JobKey("job2", "group2");
JobDetail jobA = JobBuilder.newJob(AJob.class).withIdentity(keyA).build(); // 未使用
JobDetail jobB = JobBuilder.newJob(BJob.class).withIdentity(keyB).build();
Trigger trigger =
TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group2")
.startNow()
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(1000) // 1秒間隔
.repeatForever()) // 処理をずっと繰り返す
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getListenerManager().addJobListener(new AListener(), KeyMatcher.keyEquals(keyA));
// AListenerを登録,keyAのジョブを監視
scheduler.scheduleJob(jobB, trigger); // job Bをスケジューリング
scheduler.start(); // スタート
Thread.sleep(10000); // 10秒スリープ
scheduler.shutdown(); // エンド
} catch (SchedulerException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
ジョブBは実行されますが、監視しているのはジョブAなのでリスナーで監視できていないのがわかります。
次回、意図的にジョブの実行を拒否してjobExecutionVetoed()メソッドが実行されることを確認します。

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES20xx),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^

コメント