quartz案例

来源:互联网 发布:ups监控软件下载 编辑:程序博客网 时间:2024/06/01 08:17
MyJob.java:定义任务(需要是public) 
QuartzTest.java:主线程,用于调用任务。 

这个例子的目的是在当前运行时间的下一个整数分钟输出一行文字 

MyJob: 
Java代码  收藏代码
  1. public class MyJob implements Job {  
  2.     @Override  
  3.     public void execute(JobExecutionContext context) throws JobExecutionException {  
  4.         System.out.println("任务正在执行,执行时间: " + Calendar.getInstance().getTime());  
  5.     }  
  6. }  


可以看到,任务很简单,MyJob 实现了Quartz的Job接口中的execute方法,任务的内容就是打印一行字。具体这个任务应该何时去执行,都在QuartzTest里面去定义实现。 

QuartzTest: 

Java代码  收藏代码
  1. public static void main(String[] args) throws Throwable {  
  2.         SchedulerFactory factory = new StdSchedulerFactory();  
  3.         // 从工厂里面拿到一个scheduler实例  
  4.         Scheduler scheduler = factory.getScheduler();  
  5.         // 计算任务的开始时间,DateBuilder.evenMinuteDate方法是取下一个整数分钟  
  6.         Date runTime = DateBuilder.evenMinuteDate(new Date());  
  7.         // 真正执行的任务并不是Job接口的实例,而是用反射的方式实例化的一个JobDetail实例  
  8.         JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1""group1").build();  
  9.         // 定义一个触发器,startAt方法定义了任务应当开始的时间  
  10.         Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1""group1").startAt(runTime).build();  
  11.         // 将任务和Trigger放入scheduler  
  12.         scheduler.scheduleJob(job, trigger);  
  13.         scheduler.start();  
  14.         try {  
  15.             // 等待65秒,保证下一个整数分钟出现,这里注意,如果主线程停止,任务是不会执行的  
  16.             Thread.sleep(65L * 1000L);  
  17.         } catch (Exception e) {  
  18.   
  19.         }  
  20.         // scheduler结束  
  21.         scheduler.shutdown(true);  
  22.     }  


通过代码可以看到几个重要的类: 
  • JobDetail: 真正的任务内容,任务本身是集成Job接口的,但是真正的任务是JobBuilder通过反射的方式实例化的,
  • Trigger: 触发器,定义任务应当开始的时间,主要分为两类SimpleTrigger,CronTrigger,当前例子的就是简单触发器,CronTrigger主要用于处理quartz表达式定义的任务,比如每个月20号,每个星期一之类的。

  • Scheduler: 计划表(可能翻译的不太贴切),现在我们有了要做的内容,有了要做的时间,接下来,就把这两个内容填充到计划任务Scheduler对象里面,到了时间它就可以自动运行了。

顺大便回顾一下Quartz的基本使用方法,联系windows自带的计划任务,假想场景如下: 
  • 1.我要让电脑查杀病毒(对应Quartz: 实现Job接口的execute方法,后期通过反射实例化JobDetail对象)。
  • 2.我想让电脑在五分钟之后做查杀病毒这个job(对应Quartz:通过TriggerBuilder来new出一个时间为五分钟之后的Trigger)。
  • 3.把上面我想象到的时间:五分钟之后;任务:查杀病毒 放到windows的定时任务当中,点击确定(对应Quartz:通过SchedulerFactory拿到Scheduler实例,将JobDetail与Trigger通过scheduleJob方法注册到Scheduler中,再调用start方法就可以了)。


下面先对MyJob做个小改动,让我们定义的任务Key打印出来。 

Java代码  收藏代码
  1. public class MyJob implements Job {  
  2.     @Override  
  3.     public void execute(JobExecutionContext context) throws JobExecutionException {  
  4.                 // @NOTICE JobExecutionContext 是任务执行的上下文,可以拿到任务的Key  
  5.         String jobName = context.getJobDetail().getKey().getName();  
  6.         System.out.println("任务Key:" + jobName + " 正在执行,执行时间: " + Calendar.getInstance().getTime());  
  7.     }  
  8. }  


接下来这个小例子是QuartzMultiJobTest.java,是个多任务例子,比如说,我想让我的任务五秒钟后执行,并且开始执行之后,隔三秒钟再执行一次,再隔三秒钟再执行一次,实现如下,注意@NOTICE标记: 

Java代码  收藏代码
  1. public class QuartzMultiJobTest {  
  2.     public static void main(String[] args) throws Throwable {  
  3.         SchedulerFactory factory = new StdSchedulerFactory();  
  4.         Scheduler scheduler = factory.getScheduler();  
  5.         // @NOTICE 任务的开始时间,nextGivenSecondDate方法表示:当前时间之后,每当秒数是13的倍数都是触发时间,当然只触发一次  
  6.         // 比如:00:00:12秒开始主线程,则13秒就会触发任务,如果00:00:14秒开始主线程,则在26秒触发任务  
  7.         Date runTime = DateBuilder.nextGivenSecondDate(null13);  
  8.         JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1""group1").build();  
  9.         Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1""group1").startAt(runTime).build();  
  10.         scheduler.scheduleJob(job, trigger);  
  11.           
  12.         // @NOTICE 将同一个Job实现作为另外一个任务注册到scheduler,注意名字要区分  
  13.         job = JobBuilder.newJob(MyJob.class).withIdentity("job2""group1").build();  
  14.         trigger = TriggerBuilder.newTrigger().withIdentity("trigger2""group1").startAt(runTime).build();  
  15.         scheduler.scheduleJob(job, trigger);  
  16.   
  17.         // @NOTICE 重复执行,job3表示第一次执行完之后,每隔3秒钟执行一次,重复5次,withRepeatCount参数不包括第一次执行那次,即job3总共执行6次  
  18.         job = JobBuilder.newJob(MyJob.class).withIdentity("job3""group1").build();  
  19.         trigger = TriggerBuilder.newTrigger().withIdentity("trigger3""group1")  
  20.                 .withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(5).withIntervalInSeconds(3)).startAt(runTime).build();  
  21.         scheduler.scheduleJob(job, trigger);  
  22.   
  23.         scheduler.start();  
  24.         try {  
  25.             // 等待20秒  
  26.             Thread.sleep(20L * 1000L);  
  27.         } catch (Exception e) {  
  28.   
  29.         }  
  30.         scheduler.shutdown(true);  
  31.     }  
  32. }  


主要需要理解的是 
1.DateBuilder.nextGivenSecondDate这个方法的执行时间 
2.同一个任务可以多次注册 
3.重复执行需要在Trigger的设置里面加入SimpleScheduleBuilder,设置重复次数和重复时间即可。repeatForever()方法永远表示一直重复执行。 
4.有三个API用法没放到例子中: 
  a.scheduler.addJob(job, true); //无trigger注册,表示任务立即执行。 
  b.scheduler.rescheduleJob(trigger.getKey(), trigger); //在scheduler.start之后调用,可以在job开始后重新定义trigger,然后重新注册。 
  c.scheduler.getMetaData().getNumberOfJobsExecuted() 可以在shutdown后取出执行的任务数量,一些基本信息封装在SchedulerMetaData对象中。


前面讲的都是简单触发器,直接传入一个时间让任务执行,这一话讲CronTrigger的例子。 

CronTrigger也是Quartz最重要的特色之一,通过Quartz特有的Cron表达式来确定某类时间,能完成类似"每个月二十号XXX,每个星期三XXX"之类的任务。 

先对MyJob做个小的修改,时间用中文来输出,不然看起来太费劲,逻辑上没有任何修改。 

Java代码  收藏代码
  1. public class MyJob implements Job {  
  2.     @Override  
  3.     public void execute(JobExecutionContext context) throws JobExecutionException {  
  4.         String jobName = context.getJobDetail().getKey().getName();  
  5.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");  
  6.         System.out.println("任务Key:" + jobName + " 正在执行,执行时间: " + dateFormat.format(Calendar.getInstance().getTime()));  
  7.     }  
  8. }  


接下来创建QuartzCronTest.java,这里采用了CronTrigger作为触发器,注意NOTICE注释下面的代码: 

Java代码  收藏代码
  1. public class QuartzCronTest {  
  2.   
  3.     public static void main(String[] args) throws Throwable {  
  4.         SchedulerFactory factory = new StdSchedulerFactory();  
  5.         Scheduler scheduler = factory.getScheduler();  
  6.   
  7.         JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1""group1").build();  
  8.         // @NOTICE  
  9.         // 与SimpleTrigger对比:类不同了,现在的是Trigger的子类CronTrigger;withSchedule中的参数变为CronScheduleBuilder了  
  10.         // CronScheduleBuilder可以通过类似"0/13 * * * * ?"这种表达式来创建定时任务  
  11.         // 当前这个表达式的定义是每个秒是13的倍数,或者是0的时候,都触发任务  
  12.         CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1""group1")  
  13.                 .withSchedule(CronScheduleBuilder.cronSchedule("0/13 * * * * ?")).build();  
  14.   
  15.         scheduler.scheduleJob(job, trigger);  
  16.   
  17.         scheduler.start();  
  18.         try {  
  19.             // 等待60秒查看效果  
  20.             Thread.sleep(60L * 1000L);  
  21.         } catch (Exception e) {  
  22.         }  
  23.         scheduler.shutdown(true);  
  24.     }  
  25. }  
  26. /* 
  27. -------------------------------------- 
  28.     0 0 12 * * ?            每天12点触发 
  29.     0 15 10 ? * *           每天10点15分触发 
  30.     0 15 10 * * ?           每天10点15分触发 
  31.     0 15 10 * * ? *         每天10点15分触发 
  32.     0 15 10 * * ? 2005      2005年每天10点15分触发 
  33.     0 * 14 * * ?            每天下午的 2点到2点59分每分触发 
  34.     0 0/5 14 * * ?          每天下午的 2点到2点59分(整点开始,每隔5分触发) 
  35.     0 0/5 14,18 * * ?       每天下午的 2点到2点59分(整点开始,每隔5分触发) 每天下午的 18点到18点59分(整点开始,每隔5分触发) 
  36.     0 0-5 14 * * ?          每天下午的 2点到2点05分每分触发 
  37.     0 10,44 14 ? 3 WED      3月分每周三下午的 2点10分和2点44分触发 
  38.     0 15 10 ? * MON-FRI     从周一到周五每天上午的10点15分触发 
  39.     0 15 10 15 * ?          每月15号上午10点15分触发 
  40.     0 15 10 L * ?           每月最后一天的10点15分触发 
  41.     0 15 10 ? * 6L          每月最后一周的星期五的10点15分触发 
  42.     0 15 10 ? * 6L 2002-2005    从2002年到2005年每月最后一周的星期五的10点15分触发 
  43.     0 15 10 ? * 6#3         每月的第三周的星期五开始触发 
  44.     0 0 12 1/5 * ?          每月的第一个中午开始每隔5天触发一次 
  45.     0 11 11 11 11 ?         每年的11月11号 11点11分触发(光棍节) 
  46. -------------------------------------- 
  47.  */  


其实使用起来很简单,把Trigger的传入“升级”为CronTrigger就可以了,通过CronScheduleBuilder把"0 0 12 * * ?"这样的Cron表达式传入CronTrigger当中,任务就可以在指定的时间自动执行啦。