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(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント