熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Timer,Quartz和Spring實現作業調度

2013-11-23 19:33:12  來源: Java核心技術 

  一javautilTimer

  在Java中有一個任務處理類javautilTimer非常方便於處理由時間觸發的事件任務只需建立一個繼承javautilTimerTask的子類重載父類的run()方法實現具體的任務然後調用Timer的public void schedule(TimerTask task long delay long period)方法實現任務的調度

  但是這種方法只能實現簡單的任務調度不能滿足任務調度時間比較復雜的需求比如希望系統在每周的工作日的時向系統用戶給出一個提示這種方法實現起來就困難了還有更為復雜的任務調度時間要求

  二Quartz

  OpenSymphony 的Quartz提供了一個比較完美的任務調度解決方案

  Quartz 是個開源的作業調度框架為在 Java 應用程序中進行作業調度提供了簡單卻強大的機制

  Quartz中有兩個基本概念作業和觸發器作業是能夠調度的可執行任務觸發器提供了對作業的調度

  作業

  實現 orgquartzjob 接口實現接口方法 public void execute(JobExecutionContext context) throws JobExecutionException在這個方法實現具體的作業任務

  代碼例子

  java 代碼

  execute 方法接受一個 JobExecutionContext 對象作為參數這個對象提供了作業實例的運行時上下文它提供了對調度器和觸發器的訪問這兩者協作來啟動作業以及作業的 JobDetail 對象的執行Quartz 通過把作業的狀態放在 JobDetail 對象中並讓 JobDetail 構造函數啟動一個作業的實例分離了作業的執行和作業周圍的狀態JobDetail 對象儲存作業的偵聽器群組數據映射描述以及作業的其他屬性

  觸發器

  觸發器可以實現對任務執行的調度Quartz 提供了幾種不同的觸發器復雜程度各不相同

  簡單觸發器

  public void task() throws SchedulerException {

  // Initiate a Schedule Factory

  SchedulerFactory schedulerFactory = new StdSchedulerFactory();

  // Retrieve a scheduler from schedule factory

  Scheduler scheduler = schedulerFactorygetScheduler();

  // current time

  long ctime = SystemcurrentTimeMillis();

  // Initiate JobDetail with job name job group and executable job class

  JobDetail jobDetail =

  new JobDetail(jobDetails jobDetailGroups SimpleQuartzJobclass);

  // Initiate SimpleTrigger with its name and group name

  SimpleTrigger simpleTrigger =

  new SimpleTrigger(simpleTrigger triggerGroups);

  // set its start up time

  simpleTriggersetStartTime(new Date(ctime));

  // set the interval how often the job should run ( seconds here)

  simpleTriggersetRepeatInterval();

  // set the number of execution of this job set to times

  // It will run time and exhaust

  simpleTriggersetRepeatCount();

  // set the ending time of this job

  // We set it for seconds from its startup time here

  // Even if we set its repeat count to

  // this will stop its process after repeats as it gets it endtime by then

  // simpleTriggersetEndTime(new Date(ctime + L));

  // set priority of trigger If not set the default is

  // simpleTriggersetPriority();

  // schedule a job with JobDetail and Trigger

  schedulerscheduleJob(jobDetail simpleTrigger);

  // start the scheduler

  schedulerstart();

  }

  首先實例化一個 SchedulerFactory獲得調度器創建 JobDetail 對象時它的構造函數要接受一個 Job 作為參數SimpleTrigger 是一個簡單的觸發器在創建對象之後設置幾個基本屬性以立即調度任務然後每 秒重復一次直到作業被執行

  Cron觸發器

  CronTrigger 支持比 SimpleTrigger 更具體強大的調度實現起來卻不是很復雜CronTrigger基於 cron 表達式支持類似日歷的重復間隔更為復雜的調度時間上的要求

  Cron 表達式包括以下 個字段

  ·秒

  ·分

  ·小時

  ·月內日期

  ·月

  ·周內日期

  ·年(可選字段)

  Cron 觸發器利用一系列特殊字符如下所示

  ·反斜線(/)字符表示增量值例如在秒字段中/代表從第 秒開始 秒一次

  ·問號(?)字符和字母 L 字符只有在月內日期和周內日期字段中可用問號表示這個字段不包含具體值所以如果指定月內日期可以在周內日期字段中插入?表示周內日期值無關緊要字母 L 字符是 last 的縮寫放在月內日期字段中表示安排在當月最後一天執行在周內日期字段中如果L單獨存在就等於否則代表當月內周內日期的最後一個實例所以L表示安排在當月的最後一個星期日執行

  ·在月內日期字段中的字母(W)字符把執行安排在最靠近指定值的工作日W放在月內日期字段中表示把執行安排在當月的第一個工作日內

  ·井號(#)字符為給定月份指定具體的工作日實例MON#放在周內日期字段中表示把任務安排在當月的第二個星期一

  ·星號(*)字符是通配字符表示該字段可以接受任何可能的值

  所有這些定義看起來可能有些嚇人但是只要幾分鐘練習之後cron 表達式就會顯得十分簡單

  下面的代碼顯示了 CronTrigger 的一個示例請注意 SchedulerFactoryScheduler 和 JobDetail 的實例化與 SimpleTrigger 示例中的實例化是相同的在這個示例中只是修改了觸發器這裡指定的 cron 表達式(/ * * * * ?)安排任務每 秒執行一次

  public void task() throws SchedulerException {

  // Initiate a Schedule Factory

  SchedulerFactory schedulerFactory = new StdSchedulerFactory();

  // Retrieve a scheduler from schedule factory

  Scheduler scheduler = schedulerFactorygetScheduler();

  // current time

  long ctime = SystemcurrentTimeMillis();

  // Initiate JobDetail with job name job group and executable job class

  JobDetail jobDetail =

  new JobDetail(jobDetail jobDetailGroup SimpleQuartzJobclass);

  // Initiate CronTrigger with its name and group name

  CronTrigger cronTrigger = new CronTrigger(cronTrigger triggerGroup);

  try {

  // setup CronExpression

  CronExpression cexp = new CronExpression(/ * * * * ?);

  // Assign the CronExpression to CronTrigger

  cronTriggersetCronExpression(cexp);

  } catch (Exception e) {

  eprintStackTrace();

  }

  // schedule a job with JobDetail and Trigger

  schedulerscheduleJob(jobDetail cronTrigger);

  // start the scheduler

  schedulerstart();

  }

  三Spring + Quartz

  spring對Java的Timer類和Quartz都提供了一個抽象層使用我們可以更方便地使用它們

  spring與Timer的集成

  首先是一個定時器任務

  public class EmailReportTask extends TimerTask {

  public EmailReportTask() {

  }

  public void run() {

  courseServicesendCourseEnrollmentReport();

  }

  private CourseService courseService;

  public void setCourseService(CourseService courseService) {

  urseService = courseService;

  }

  }

  spring配置文件中配置EmailReportTask

  <bean id=reportTimerTask

       class=comspringinactiontrainingscheduleEmailReportTask>

            <property name=courseService>

            <ref bean=courseService/>

       </property>

  </bean>

  調度定時器任務

  xml 代碼

  <bean id=scheduledReportTask

  

            class=orgspringframeworkschedulingtimerScheduledTimerTask>

  

  

            <property name=timerTask>

  

                  <ref bean=reportTimerTask/>

  

            property>

  

            <property name=period>

  

                  <value><value>

  

  

            property>

  

            <property name=delay>

  

                  <value>value>

  

            property>

  

  bean>

  

  啟動定時器

  xml 代碼

  <bean class=orgspringframeworkschedulingtimerTimerFactoryBean>

        <property name=scheduledTimerTasks>

              <list>

                    <ref bean=scheduledReportTask/>

              list>

        property>

  bean>

  spring與Quartz的集成

  創建一個工作

  public class EmailReportJob extends QuartzJobBean {

  

      public EmailReportJob() {

  

       }

  

      protected void executeInternal(JobExecutionContext context)  throws JobExecutionException {

           courseServicesendCourseEnrollmentReport();

       }

  

      private CourseService courseService;

      public void setCourseService(CourseService courseService) {

          urseService = courseService;

       }

  }

  在spring配置文件的配置EmailReportJob

  <bean id=reportJob

        class=orgspringframeworkschedulingquartzJobDetailBean>

        <property name=jobClass>

             <value>comspringinactiontrainingscheduleEmailReportJobvalue>

        property>

        <property name=jobDataAsMap>

             <map>

                  <entry key=courseService>

                       <ref bean=courseService/>

                  entry>

             map>

        property>

  bean>

  調度工作

  和quartz對應Spirng提供了兩個觸發器SimpleTriggerBean和CronTriggerBean

  使用SimpleTriggerBean觸發器

  <bean id=simpleReportTrigger

       class=orgspringframeworkschedulingquartzSimpleTriggerBean>

       <property name=jobDetail>

            <ref bean=reportJob/>

       property>

       <property name=startDelay>

            <value>value>

       property>

       <property name=repeatInterval>

            <value>value>

       property>

  bean>

  使用CronTriggerBean觸發器

  <bean id=cronReportTrigger

            class=orgspringframeworkschedulingquartzCronTriggerBean>

       <property name=jobDetail>

            <ref bean=reportJob/>

       property>

       <property name=cronExpression>

            <value> * * * * ?value>

       property>

  bean>

  系統會在每分鐘的秒執行調度任務


From:http://tw.wingwit.com/Article/program/Java/hx/201311/27082.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.