虽然上一讲中说明,在实际应用中很少用到Quartz实现固定执行次数,但是我就是那个钻牛角尖的人.废话不多,代码如下:
实现思路:
1. 在上一讲中说明Quartz的JobDetail可以是无状态的,也可以是有状态的。Trigger无状态的,所以只能使用JobDetail有状态的子接口StatefulJob.Job代码如下:
package test.quartz.spring; import java.util.Date; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.StatefulJob; public class TJob implements StatefulJob { /** * 不用挣扎了,Quartz都是无状态的,他不知道执行了几次。 * 如果想要记录状态就需要持久化到数据库. */ public void execute(JobExecutionContext cntxt) throws JobExecutionException { JobDataMap jobDataMap = cntxt.getJobDetail().getJobDataMap(); Integer count = (Integer) jobDataMap.get("count"); if(count==null){ count=0; } count++; System.out.println("杨春龙,太帅了"); System.out.println("不是我说的"); System.out.println( " Generating report - " + count + "-" + new Date()); jobDataMap.put("count", count); cntxt.getJobDetail().setJobDataMap(jobDataMap); } }
根据ApI描述,如果是有状态的Job,所有的Job都共享jobDataMap,所有把执行次数记录下来.虽然我记录了执行次数,但是因为Job是一个Thread,由ThreadPool来维持,那么如何监视Job的执行情况,在看源码中,发现有一个Listener,可以监听进程的执行,代码如下:
package test.quartz.spring; import org.quartz.CronTrigger; import org.quartz.JobExecutionContext; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.listeners.TriggerListenerSupport; public class TriggerListener extends TriggerListenerSupport { private String name; private Integer count; public void setName(String name) { this.name=name; } public String getName() { // TODO Auto-generated method stub return this.name; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } @Override public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode) { System.out.println("Trigger :"+trigger.getGroup()+"."+trigger.getName()+" completed with code:"+triggerInstructionCode); Integer current = (Integer) context.getJobDetail().getJobDataMap().get("count"); System.out.println("调用次数:"+current); if(current == count){ try { context.getScheduler().shutdown(); } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); } } super.triggerComplete(trigger, context, triggerInstructionCode); } }
在Job的执行中设置执行次数,在监听器中得到执行次数,当执行次数到达count的时候退出执行.
JobQuartz.xml配置如下
triggerListener 3 test.quartz.spring.TJob
triggerListener 0/10 * * * * ?
在SchedulerFactoryBean中配置监听器列表,在CronTriggerBean配置监听器名称,这样这个监听器就可以监听这个Trigger了,当执行了3次后自动退出
测试代码如下:
package test.quartz.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring { /** * @param args */ public static void main(String[] args) { System.out.println("测试开始"); ApplicationContext ctx = new ClassPathXmlApplicationContext("JobQuartz.xml"); System.out.println("测试结束"); } }
测试输出如下:
测试开始
2010-09-27 09:33:39,640 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] -2010-09-27 09:33:39,718 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - 2010-09-27 09:33:39,781 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - 2010-09-27 09:33:39,812 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - 2010-09-27 09:33:39,953 INFO [org.quartz.core.SchedulerSignalerImpl] - 2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - 2010-09-27 09:33:39,953 INFO [org.quartz.simpl.RAMJobStore] - 2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - 2010-09-27 09:33:39,953 INFO [org.quartz.impl.StdSchedulerFactory] - 2010-09-27 09:33:39,953 INFO [org.quartz.impl.StdSchedulerFactory] - 2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - 2010-09-27 09:33:39,953 INFO [org.springframework.scheduling.quartz.SchedulerFactoryBean] - 2010-09-27 09:33:39,953 INFO [org.quartz.core.QuartzScheduler] - 测试结束 杨春龙,太帅了 不是我说的 Generating report - 1-Mon Sep 27 09:33:40 CST 2010 Trigger :DEFAULT.cron completed with code:0 调用次数:1 杨春龙,太帅了 不是我说的 Generating report - 2-Mon Sep 27 09:33:50 CST 2010 Trigger :DEFAULT.cron completed with code:0 调用次数:2 杨春龙,太帅了 不是我说的 Generating report - 3-Mon Sep 27 09:34:00 CST 2010 Trigger :DEFAULT.cron completed with code:0 调用次数:3 2010-09-27 09:34:00,000 INFO [org.quartz.core.QuartzScheduler] - 2010-09-27 09:34:00,000 INFO [org.quartz.core.QuartzScheduler] - 2010-09-27 09:34:00,000 INFO [org.quartz.core.QuartzScheduler] -