※文檔
官網教學連結
官網設定教學連結
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