※文檔
官網教學連結官網設定教學連結
W3Cschool Quartz 官網
好心網友翻譯的連結:
第一課 使用 Quartz
第二課 Quartz API,Jobs 和 Triggers 介紹
第三課 關於更多的 Jobs和 JobDetails
第四課 關於更多的 Triggers
第五課 SimpleTriggers
第六課 CronTriggers
第七課 TriggerListeners & JobListeners
第八課 SchedulerListeners
第九課 JobStores
第十課 Configuration, Resource Usage和SchedulerFactory
第十一課 進階(企業)功能
第十二課 Quartz 其他功能
※Hello Quartz
import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; public class TestQuartz { public static void main(String[] args) { JobDetail job = JobBuilder.newJob(MyJob.class) .withIdentity("myJob1", "group1") .build(); Trigger trigger = TriggerBuilder .newTrigger() .withIdentity("myTrigger1", "group2") .startNow() .withSchedule(SimpleScheduleBuilder .simpleSchedule() .withIntervalInSeconds(3) .repeatForever()) .build(); System.out.println(job.getKey()); // group1.myJob1 System.out.println(trigger.getKey());// group2.myTrigger1 try { SchedulerFactory schedFact = new StdSchedulerFactory(); Scheduler sched = schedFact.getScheduler(); System.out.println(trigger.getJobKey()); // null sched.scheduleJob(job, trigger); System.out.println(trigger.getJobKey()); // 註冊之後才能取得 group1.myJob1 sched.start(); } catch (SchedulerException e) { e.printStackTrace(); } } }
※注意官網有靜態 import,如下:
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
之後的代碼,我也會用這種方式
※假設 SchedulerFactory 和 Scheduler 寫在最上面,然後馬上就 start(),最後在呼叫 JobDetail、
Trigger並註冊 scheduleJob,也是可以運行的
※
public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("xxxxxxxxxxxxx"); } }
※Job 就是時間到後要執行的方法
※JobDataMap
JobDetail job = newJob(MyJob.class) .withIdentity("myJob", "group1") .usingJobData("aaa", "111") .usingJobData("bbb", 222) .build(); Trigger trigger = newTrigger() .withIdentity("myTrigger1", "group2") .startNow() .withSchedule(simpleSchedule() .withIntervalInSeconds(3) .repeatForever()) .build(); try { SchedulerFactory schedFact = new StdSchedulerFactory(); Scheduler sched = schedFact.getScheduler(); sched.scheduleJob(job, trigger); sched.start(); } catch (SchedulerException e) { e.printStackTrace(); }
※使用 JobDataMap 可以塞值
※
public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobKey key = context.getJobDetail().getKey(); // JobDataMap dataMap = context.getMergedJobDataMap(); JobDataMap dataMap = context.getJobDetail().getJobDataMap(); String a = dataMap.getString("aaa"); int b = dataMap.getInt("bbb"); System.out.println("key=" + key); // group1.myJob System.out.println("a=" + a); // 111 System.out.println("b=" + b);// 222 } }
※取值時,可以使用 getMergedJobDataMap() 或 getJobDetail().getJobDataMap(),但還是有區別的,看下面的 @PersistJobDataAfterExecution
※@DisallowConcurrentExecution
JobDetail job = newJob(MyJob.class).withIdentity("myJob", "group1").build(); Trigger trigger = newTrigger() .withIdentity("myTrigger1", "group2") .startNow() .withSchedule(simpleSchedule() .withIntervalInSeconds(3) .repeatForever()) .build(); try { SchedulerFactory schedFact = new StdSchedulerFactory(); Scheduler sched = schedFact.getScheduler(); sched.scheduleJob(job, trigger); sched.start(); } catch (SchedulerException e) { e.printStackTrace(); }
※
※
@DisallowConcurrentExecution public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { System.out.println("前=" + new Date()); Thread.sleep(5000); System.out.println("後=" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } }
※我設定每3秒執行一次,但 Job 裡會睡 5 秒,所以我還沒加這個註解前會是如下的結果:
前=Tue Aug 21 14:17:44 SGT 2018
前=Tue Aug 21 14:17:47 SGT 2018
後=Tue Aug 21 14:17:49 SGT 2018
前=Tue Aug 21 14:17:50 SGT 2018
後=Tue Aug 21 14:17:52 SGT 2018
前=Tue Aug 21 14:17:53 SGT 2018
後=Tue Aug 21 14:17:55 SGT 2018
前=Tue Aug 21 14:17:56 SGT 2018
後=Tue Aug 21 14:17:58 SGT 2018
前=Tue Aug 21 14:17:59 SGT 2018
後=Tue Aug 21 14:18:01 SGT 2018
前=Tue Aug 21 14:18:02 SGT 2018
後=Tue Aug 21 14:18:04 SGT 2018
※44~49 才是一組,中間會有下一次的執行,但如果加上這個註解,結果如下:
前=Tue Aug 21 14:19:12 SGT 2018
後=Tue Aug 21 14:19:17 SGT 2018
前=Tue Aug 21 14:19:17 SGT 2018
後=Tue Aug 21 14:19:22 SGT 2018
前=Tue Aug 21 14:19:22 SGT 2018
後=Tue Aug 21 14:19:27 SGT 2018
前=Tue Aug 21 14:19:27 SGT 2018
後=Tue Aug 21 14:19:32 SGT 2018
前=Tue Aug 21 14:19:32 SGT 2018
後=Tue Aug 21 14:19:37 SGT 2018
前=Tue Aug 21 14:19:37 SGT 2018
※此時中間沒有插入下一次的執行,是以執行完為主的
※@PersistJobDataAfterExecution
JobDetail job = newJob(MyJob.class) .withIdentity("myJob", "group1") .usingJobData("aaa", "111") .usingJobData("bbb", 222) .build(); Trigger trigger = newTrigger() .withIdentity("myTrigger1", "group2") .startNow() .withSchedule(simpleSchedule() .withIntervalInSeconds(3) .repeatForever()) .build(); try { SchedulerFactory schedFact = new StdSchedulerFactory(); Scheduler sched = schedFact.getScheduler(); sched.scheduleJob(job, trigger); sched.start(); } catch (SchedulerException e) { e.printStackTrace(); }
※
※
@PersistJobDataAfterExecution public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // JobDataMap dataMap = context.getMergedJobDataMap(); // 不會更新的 JobDataMap dataMap = context.getJobDetail().getJobDataMap(); System.out.println("a=" + dataMap.getString("aaa")); // 111|333 System.out.println("b=" + dataMap.getInt("bbb"));// 222|444 dataMap.put("aaa", "333"); dataMap.put("bbb", 444); } }
※註解的意思是執行後可保存資料,如範例的 333 和 444,有加上這個註解以及使用的是 getJobDetail().getJobDataMap() 才可以,使用 getMergedJobDataMap() 不會
※第一次執行後是 111 和 222,之後就都會是 333 和 444 了
※官網有說明加上這個註解後,要考慮是不是也要加上 @DisallowConcurrentExecution
沒有留言:
張貼留言