全ジョブへの共通情報の渡し方
Quartzによってジョブ(Jobインタフェースの実装オブジェクト)が実行される場合,JobオブジェクトにJobExecutionContextオブジェクトが渡される。これは,サーブレットのServletContextオブジェクトと同様に,実行対象のJobオブジェクトの状況(まさにコンテキスト)の情報が保持されている。 各ジョブのSchedulerへの登録は,Jobクラス(のサブクラス)のクラスオブジェクト(HogeJob.classなど)を登録することになるため,実際に実行対象となるJobインスタンスは,Schedulerオブジェクトへのジョブ登録時には存在しない。そのため,対象のジョブに必要な情報は,JobDataMapオブジェクトをJobDetailオブジェクトから取り出してput()メソッドにより格納することで,Jobインスタンスの実行時にJobExecutionContextオブジェクトから取得できるようになる。 例えば,
JobDetail jobDetail = new JobDetail(“hogeJob”, null, HogeJob.class); JobDataMap jobDataMap = jobDetail.getJobDataMap(); Object param1 = …; // 渡したい情報 jobDataMap.put(“param1”, param1); scheduler.scheduleJob(jobDetail, …);
としておくことで,
public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); Object param1 = jobDataMap.get(“param1”); }
というようにJobオブジェクト呼び出し時に取得することができる。 ただし,これは自分でSchedulerオブジェクトにジョブを登録するコードを書くときの話である。JobSchedulingDataProcessorクラスを使ってXMLファイルに定義されたジョブ情報を元にスケジューリングする方式では,XMLファイルに静的に記述可能な情報,つまりリテラルしかJobDataMapオブジェクトに格納できない。 実行時にしか手に入らない情報や情報を持つオブジェクトを各Jobオブジェクトの実行直前に渡すためには,JobListenerインタフェースが使用できる。JobListenerインタフェースは,Schedulerに登録された各ジョブの実行に関連するイベントの通知を受けるためのイベントリスナーだ。 前回のTriggerListenerインタフェースと同様に,JobListenerオブジェクトの登録先は2つ存在する。
-
各ジョブ毎
-
グローバル グローバルとは,Schedulerオブジェクトに登録された全てのジョブに対して,一括でイベント通知を受けたい場合に便利である。つまり,1つのJobListenerオブジェクトで,全ジョブに関するイベントをハンドリング可能。例えば,全てのJobオブジェクトに対して,ある情報を共通的に渡したい場合などに使用できる。
public class JobListenerImpl implements JobListener { private Object param1; public JobListenerImpl(Object param1) { this.param1 = param1; } ・・・ public void jobToBeExecuted(JobExecutionContext context) { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); jobDataMap.put(“param1”, param1); }
}
JobListener#jobToBeExecuted()メソッドは,ジョブの実行が確定し,さぁジョブを実行するぞ!というタイミングの直前にコールバックされるメソッドである。上記のJobListenerImplクラスでは,コンストラクタで受け取ったparam1オブジェクトを,jobToBeExecuted()メソッドに渡される処理対象のジョブのコンテキストに追加している様子がわかるだろう。これを,
Scheduler scheduler = …; Object param1 = …; scheduler.addGrobalJobListener(new JobListenerImpl(param1));
としてあげれば,登録された全てのジョブの実行直前に,共通的にparam1オブジェクトを渡すことができる。 ジョブをXMLファイルで記述するパターンを採用した際には,JobListenerインタフェースやTriggerListenerインタフェースを上手に使ってあげることで,ジョブを一括して処理することが可能となり,よりきめの細かいジョブスケジューリングを実現することができるようになるだろう。