1. 程式人生 > >quartz的學習和簡單使用

quartz的學習和簡單使用

以前在框架中使用過,很多都是純粹的複製貼上,瞭解過用法知道如何配置,但時間久了就沒什麼印象了,現在重新撿起來,再次進行學習。

quartz相關的介紹都已經很多了,我就不重複囉嗦,簡單說一下個人的認識和使用。

* 定時任務 quartz的設計比較合理,將排程Scheduler、觸發Trigger、任務進行分離Job(這裡使用JobDetail建立Job的例項)
* 排程Scheduler負責任務的排程執行以及任務的銷燬
* 觸發器設定Trigger事件的觸發條件或時間,分為SimpleTrigger和CronTrigger兩種常用模式,
* 當然還有其他兩種模式CalendarIntervalTrigger 按日期觸發的Trigger 和 DailyTimeIntervalTrigger 按天觸發的Trigger
* 其中CronTrigger中的設定規範基本等同於cron4j,不過增加了秒
* JobDetail是任務的定義,而Job是任務的執行邏輯

在學習cron4j的時候,我使用了的內部類,在建立quartz的時候我也同樣使用了內部類,但示例始終不能啟動,找了很長時間,沒想到這裡還有個坑,現在也不知道因為什麼。

 

下面程式碼是個反面教材,是不能執行的,需要將HelloTask類單獨出來寫才可以執行。

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import
org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger; import static org.quartz.DateBuilder.evenMinuteDate ; /** * * @author Uboobo * * 定時任務 quartz的設計比較合理,將排程Scheduler、觸發Trigger、任務進行分離Job(這裡使用JobDetail建立Job的例項) * 排程Scheduler負責任務的排程執行以及任務的銷燬 * 觸發器設定Trigger事件的觸發條件或時間,分為SimpleTrigger和CronTrigger兩種常用模式, * 當然還有其他兩種模式CalendarIntervalTrigger 按日期觸發的Trigger 和 DailyTimeIntervalTrigger 按天觸發的Trigger * 其中CronTrigger中的設定規範基本等同於cron4j,增加了秒 * JobDetail是任務的定義,而Job是任務的執行邏輯 * */ public class QuartzTask { // 建立scheduler public static void createScheduler(JobDetail job, Trigger trigger) { try { // 建立scheduler,需要捕獲排程異常 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 加入這個排程 scheduler.scheduleJob(job, trigger); // 啟動之 scheduler.start(); // 執行一段時間後關閉 Thread.sleep(10000); scheduler.shutdown(true); } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 建立Trigger public static Trigger createTrigger() { Trigger trigger = newTrigger() .withIdentity("myTrigger", "group1") .startNow() .withSchedule(simpleSchedule() .withIntervalInSeconds(10)//間隔時間是10s .repeatForever()) .build(); return trigger; } // 建立Job public static JobDetail createJob() { JobDetail job = newJob(HelloTask.class) .withIdentity("myJob", "group1") .build(); return job; } // 內部類 ,坑在這這裡,需要使用單獨的類 static class HelloTask implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDetail detail = context.getJobDetail(); // TODO Auto-generated method stub String name = detail.getJobDataMap().getString("name"); System.out.println(" my job do..." + name); } } public static void main(String[] args) throws Exception { JobDetail job = createJob(); Trigger trigger = createTrigger(); createScheduler(job,trigger); }

程式碼裡沒有標註太多註釋,這裡多說幾句,一個quartz任務要執行的話,首先要通過StdSchedulerFactory.getDefaultScheduler() 建立scheduler,只有這樣才能使用排程,然後要通過Trigger去建立一個或多個觸發器並設定執行時間,然後再去使用JobDetail建立job,再使用job去載入我們要去執行的類,最後使用排程去載入執行。

quartz的設計將其進行分層還是有很多好處,但也增加了一些複雜度,如果直接使用scheduler去呼叫job也是可以的,但如果實現多重負責設定就比較困難了。

下面貼一下可以執行的程式碼

    public static void main(String [] args)
    {
    try
    {
        // 建立scheduler
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // 定義一個Trigger
        Trigger trigger = newTrigger().withIdentity("trigger1", "group1") // 定義name/group
            .startNow()// 一旦加入scheduler,立即生效
            .withSchedule(simpleSchedule() // 使用SimpleTrigger
                    .withIntervalInSeconds(1) // 每隔一秒執行一次
                    .repeatForever()) // 一直執行,奔騰到老不停歇
            .build();

        // 定義一個JobDetail
        JobDetail job = newJob(HelloJob.class) // 定義Job類為HelloQuartz類,這是真正的執行邏輯所在
            .withIdentity("job1", "group1") // 定義name/group
            .usingJobData("name", "quartz") // 定義屬性
            .build();

        // 加入這個排程
        scheduler.scheduleJob(job, trigger);

        // 啟動之
        scheduler.start();

        // 執行一段時間後關閉
        Thread.sleep(100000);
        scheduler.shutdown(true);
        
    } catch (Exception e)
    {
        e.printStackTrace();
    }
    }
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/** 
 * hello world Quartz 
 * @author weeks 
 * 
 */
public class HelloJob implements Job
{

    private static Logger _log = LoggerFactory.getLogger(HelloJob.class);

    /** 
     * Job,Job需要一個公有的建構函式,否則Factory無法構建 
     */
    public HelloJob()
    {
    }

    /** 
     * 實現execute方法 
     */
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
    System.out.println(" my job do...");
    }
}

 

這裡還遺留一個問題,import中使用了 static 有點不太明白,設計者為什麼要這麼做,這麼做有什麼好處,待我瞭解之後再來補充。