<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kingpub

    海內存知己,博客若比鄰

     

    Quartz,企業級的計劃/日程安排(job schedule)系統(1)-介紹

    什么是job schedule system?
    ??? job schedule system是負責在預定義的時間執行或者通知某個應用組件的系統。舉個例子來說,比如在每周一早上9:30發送email通知客戶最新的業務情況。

    java.util.Timer和java.util.TimerTask
    ??? Timer和TimerTask是可以完成job schedule的兩個jdk提供的類,不過這不能稱為一個system。Timer和TimerTask是很簡單的,不直接支持持久化任務,線程池和類似日歷(calendar-like)的計劃安排,在完成一些高級功能上開發人員要進行大量的擴展。

    Quartz的簡單介紹
    ??? Quartz是opensymphony組織專攻job scheduling領域又一個開源利器,可以到http://www.opensymphony.com/quartz查看詳細信息。Quartz是輕量級的組件,開發人員只需要加載單獨的jar包就可以利用Quartz強大的日程安排功能。當然,假如你為Quartz配備了數據庫持久化任務的特性,Quartz也可以很好的利用這一點,從而在機器重啟后還能夠記住你原先安排的計劃。

    ??? Quartz中我們接觸最多的接口使Scheduler接口,該接口的提供了計劃安排的功能,比如schedule/unschedule計劃、start/pause/stop Scheduler.

    ??? Quartz提供一些常用的Listener(JobListener,TriggerListener,SchedulerListener)用于完全的監視計劃安排和執行情況。

    開始我們的Quartz之旅

    • ?HelloWorld example:

    想必大家很想看一個HelloWorld的例子了吧,那么還是以HellowWorld開始。

    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.SchedulerFactory;
    ?import org.quartz.Trigger;
    ?import org.quartz.impl.StdSchedulerFactory;
    ?/**
    ? * @author snowway
    ? * @version $Id$
    ? */
    ?public class SayHelloWorldJob implements Job{
    ???? /*
    ????? * (non-Javadoc)
    ????? *
    ????? * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
    ????? */
    ???? public void execute(JobExecutionContext context) throws JobExecutionException{
    ???????? System.out.println("hello world!");
    ???? }

    ???? public static void main(String[] args) throws Exception{
    ???????? SchedulerFactory factory = new StdSchedulerFactory();
    ???????? Scheduler scheduler = factory.getScheduler();

    ???????? JobDetail jobDetail = new JobDetail("SayHelloWorldJob",
    ???????????????? Scheduler.DEFAULT_GROUP,
    ???????????????? SayHelloWorldJob.class);

    ???????? Trigger trigger = new SimpleTrigger("SayHelloWorldJobTrigger",
    ???????????????? Scheduler.DEFAULT_GROUP,
    ???????????????? new Date(),
    ???????????????? null,
    ???????????????? 0,
    ???????????????? 0L);
    ???????? scheduler.scheduleJob(jobDetail, trigger);
    ???????? scheduler.start();
    ???? }
    ?}

    為了簡單起見,我把main方法寫在SayHelloWorldJob中了,執行SayHelloWorldJob可以看到控制臺打印hello world.

    • ?回顧Hello World example:

    ?Job是什么?
    ?接口Job是每個業務上需要執行的任務需要實現的接口,該接口只有一個方法:

    ?package org.quartz;

    ??? public interface Job {

    ????? public void execute(JobExecutionContext context)
    ??????? throws JobExecutionException;
    ??? }

    ?execute方法也就是當時間到達后,Quartz回調的方法,我們使SayHelloWorldJob實現Job接口以提供打印功能

    ? JobDetail是什么?
    ?JobDetail描述了一個任務具體的信息,比如名稱,組名等等。
    ?JobDetail jobDetail = new JobDetail("SayHelloWorldJob",
    ???????????????? Scheduler.DEFAULT_GROUP,
    ???????????????? SayHelloWorldJob.class);

    ?在上面的構造方法中,第一個是任務的名稱,第二個是組名,第三個就是實際當任務需要執行的回調類。

    ?Trigger是什么?
    ?Trigger顧名思義就是觸發器,Quartz有個很好的想法就是分離了任務和任務執行的條件。Trigger就是控制任務執行條件的類,當Trigger認為執行條件滿足的時刻,Trigger會通知相關的Job去執行。分離的好處是:
    ?1.你可以為某個Job關聯多個Trigger,其中任何一個條件滿足都可以觸發job執行,這樣可以完成一些組合的高級觸發條件
    ?2.當Trigger失效后(比如:一個永遠都不能滿足的條件),你不必去聲明一個新的job,代替的是你可以為job關聯一個新的Trigger讓job可以繼續執行。

    ?目前的Quartz實現中,存在兩種Trigger,SimpleTrigger和CronTrigger,SimpleTrigger用來完成一些比如固定時間執行的任務,比如:從現在開始1分鐘后等等;而CronTrigger(沒錯,和unix的cron進程的含意一樣)用來執行calendar-like的任務,比如:每周五下午3:00,每月最后一天等等。

    ?Trigger trigger = new SimpleTrigger("SayHelloWorldJobTrigger",
    ???????????????? Scheduler.DEFAULT_GROUP,
    ???????????????? new Date(),
    ???????????????? null,
    ???????????????? 0,
    ???????????????? 0L);
    ?這個構造方法中,第一個是Trigger的名稱,第二個是Trigger的組名,第三個是任務開始時間,第四個是結束時間,第五個是重復
    ?次數(使用SimpleTrigger.REPEAT_INDEFINITELY常量表示無限次),最后一個是重復周期(單位是毫秒),那么這樣就創建
    ?了一個立刻并只執行一次的任務。

    ?scheduler.scheduleJob(jobDetail, trigger);
    ?這條語句就是把job和Trigger關聯,這樣當Trigger認為應該觸發的時候就會調用(實際上是Scheduler調用)job.execute方法了。

    ?scheduler.start();
    ?千萬別忘了加上上面的語句,這條語句通知Quartz使安排的計劃生效。

    ?關于execute方法的參數JobExecutionContext
    ?JobExecutionContext就和很多Context結尾的類功能一樣,提供的運行時刻的上下文環境,JobExecutionContext中有
    ?Scheduler,JobDetail,Trigger等很多對象的引用,從而當你在execute方法內部須需要這些對象的時刻提供的便利。

    ? JobDetail和Trigger的name和group
    ?Scheduler實例對應了很多job和trigger的實例,為了方便的區分,Quartz使用name和group這兩個特性,正如你想向的一樣,
    ?同一個group下不能有兩個相同name的JobDetail,Trigger同理
    ?同一個Scheduler下不能有兩個相同group的JobDetail,Trigger同理
    ?JobDetail和Trigger的完全限定名為:group + name

    • ?更深入的思考...


    HelloWorld的例子還不足以說明一些問題,一些人可能會這樣問:假如execute方法中需要一些額外的數據怎么辦?比如說execute
    ?中希望發送一封郵件,但是我需要知道郵件的發送者、接收者等信息?

    ?存在兩種解決方案:
    ?1.JobDataMap類:
    ?? 每個JobDetail都關聯了一個JobDataMap實例,JobDataMap是java.util.Map的子類,基本上是提供key-value形式的數據,并提供了一些便利方法(主要是對java基本數據類型的支持,如put(String key,int value)),當開發人員創建JobDetail的時候,可以把附加信息放到JobDataMap中,那么在execute方法中可以根據key找到需要的值。
    ?? JobDetail job = new JobDetail....
    ?? job.getJobDataMap().put("from","snowway@vip.sina.com");
    ?? ...
    ??

    在execute中
    ?? String from = jobExecutionContext.getJobDetail().getJobDataMap().getString("from");
    ?? ....

    ?? 不過,當你使用數據庫存儲JobDetail的時候(默認情況下使用RAM),這里有一個致命的弱點,你不能把沒有實現java.io.Serializable的對象放入JobDataMap中,因為Quartz將使用Blob字段保存(也可以通過配置文件關閉)序列化過的JobDataMap中的對象。比如你在execute方法中需要一個java.sql.Connection接口實例,這種情況也是普遍的,那么通常情況下你不能把Connection放入JobDataMap,即使你只想在execute中使用。(注:讀者可暫時認為上面這段話是正確的,然而可以通過指示quartz改變這種行為,那屬于高級話題)

    ?2.假如你需要一個java.sql.Connection,用于在execute中完成某些操作,那么你可以把Connection放入Quartz的SchedulerContext中,execute也可以訪問,并且Quartz不會持久化SchedulerContext中的任何東西。

    ?? scheduler.getContext().put("java.sql.Connection",connection);??

    ?execute中
    ?? Connection con = (Connection)jobExecutionContext.getScheduler().getContext().get("java.sql.Connection");

    ?未完待續...

    posted on 2006-06-05 12:28 xiaofeng 閱讀(539) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    收藏夾

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲爆乳少妇无码激情| 亚洲永久中文字幕在线| 美女18一级毛片免费看| 国产男女性潮高清免费网站| 精品国产成人亚洲午夜福利| 在线观看免费人成视频色| 亚洲AV无码乱码在线观看代蜜桃| 亚洲免费观看在线视频| 亚洲精品第一国产综合野| aa级一级天堂片免费观看| 亚洲精华国产精华精华液好用 | 亚洲AV无码AV日韩AV网站| 日韩午夜免费视频| 免费一级毛片在线播放视频免费观看永久 | 久久精品免费一区二区| 亚洲中文字幕AV每天更新| 国产片免费福利片永久| 日韩免费在线中文字幕| 亚洲精品成人无码中文毛片不卡| 美女被cao网站免费看在线看| 久久精品国产亚洲av日韩| 好男人视频在线观看免费看片| 国产天堂亚洲精品| 亚洲热线99精品视频| 国产精品1024永久免费视频| 亚洲无吗在线视频| 久久亚洲国产精品五月天婷| 一区二区三区福利视频免费观看| 亚洲人精品亚洲人成在线| 亚洲精品国产va在线观看蜜芽| 日韩电影免费在线观看| 亚洲人成网站色在线观看| 亚洲精品视频在线看| 亚洲黄色免费电影| 污视频网站免费观看| 精品亚洲aⅴ在线观看| 国产三级免费观看| 24小时在线免费视频| 美女又黄又免费的视频| 亚洲日本va午夜中文字幕一区| 好先生在线观看免费播放|