Quartz定时器2Quartz是什么Quartz能干什么EasyexampleQuartz框架分析项目开发3Quartz是什么?Quartz是OpenSymphony开源组织在Jobscheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或EJBs。Quartz是一个任务日程管理系统,一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。4Quartz能干什么?场景#1:下载交易流水从银行下载当日交易流水场景#2:邮件提醒和告警公司出于安全考虑,让每个员工三个月换一次邮箱密码。这种情况下,可以创建一个作业,让它每天午夜运行一次,并且向离过期时间不到三天的所有用户发邮件提醒。这里可以恰到好处的用到作业调度器。图1.1描绘了密码这个提醒作业。图1.1密码过期的作业每晚发送邮件给密码很快会过期的用户5Easyexample//FirstwemustgetareferencetoaschedulerSchedulerFactorysf=newStdSchedulerFactory();Schedulersched=sf.getScheduler();//computeratimethatisonthenextroundminuteDaterunTime=TriggerUtils.getEvenMinuteDate(newDate());//definethejobandtieittoourHelloJobclassJobDetailjob=newJobDetail(job1,group1,HelloJob.class);//TriggerthejobtorunonthenextroundminuteTriggertrigger=newSimpleTrigger(trigger1,group1,runTime);//Tellquartztoschedulethejobusingourtriggersched.scheduleJob(job,trigger);//Startuptheschedulersched.start();6下载=下载:docs/wikidocsQuartz的帮助文件docs/apiQuartz框架的JavaDocApi说明文档ExamplesQuartz的例子LibQuartz使用到的第三方包src源码7Quartz框架分析核心接口SchedulerJobJobDetailTriggerJobDataMap8Scheduler(调度器)ASchedulermaintainsaregisteryoforg.quartz.JobDetailsandTriggers.Onceregistered,theSchedulerisresponibleforexecutingJobswhentheirassociatedTriggersfire(whentheirscheduledtimearrives).voidaddJob(JobDetailjobDetail,booleanreplace)throwsSchedulerException;DatescheduleJob(Triggertrigger)throwsSchedulerException;DatescheduleJob(JobDetailjobDetail,Triggertrigger)throwsSchedulerException;DaterescheduleJob(StringtriggerName,StringgroupName,TriggernewTrigger)throwsSchedulerException;9Scheduler(调度器)客服端与调度器交互是通过org.quartz.Scheduler接口的。这个Scheduler的实现,实际上是一个代理,对其中方法调用会传递到QuartzScheduler实例上。QuartzScheduler处在框架根的位置,它是一个引擎驱动着整个框架。Quartz相当灵活和可配置,许多重要的功能由分离的组件和子框架实现,所以并非所有的功能都直接内建到QuartzScheduler。这就意味着用户可以用自己某个关键特征实现来替换原有默认实现。10Scheduler实例化使用scheduler之前应首先实例化它。使用SchedulerFactory可以完成scheduler的实例化。org.quartz.impl.DirectoSchedulerFactoryorg.quartz.impl.StdSchedulerFactoryStdSchedulerFactory会加载类路径下的quartz.properties文件。quartz.properties,允许你修改框架运行时环境。缺省是使用Quartz.jar里面的quartz.properties文件。当然,你应该创建一个quartz.properties文件的副本并且把它放入你工程的classes目录中以便类装载器找到它。11Scheduler启动关闭一旦一个scheduler被实例化,它就可以被启动(start),并且处于驻留模式,直到被关闭(shutdown)。注意,一旦scheduler被关闭(shutdown),则它不能再重新启动,除非重新实例化它。除非scheduler被启动并且不处于暂停状态,否则触发器不会被触发(任务也不能被执行)。voidstart()throwsSchedulerException;voidstartDelayed(intseconds)throwsSchedulerException;voidshutdown()throwsSchedulerException;voidshutdown(booleanwaitForJobsToComplete)throwsSchedulerException;12Job作业是一个执行任务的简单java类。任务可以是任何java代码。只需你实现org.quartz.Job接口。当Quartz确定该是作业运行的时候,它将调用你的作业。Quartz提供了一个机制来建立具有不同粒度的、可重复的调度表,于是,你只需创建一个java类,这个类被调用而执行任务。publicinterfaceJob{voidexecute(JobExecutionContextcontext)throwsJobExecutionException;}13JobDetailJobDetail对象由Quartz客户端在Job被加入到scheduler时创建。它包含了Job的各种设置属性以及一个JobDataMap对象,这个对象被用来存储给定Job类实例的状态信息。Scheduler并不保存真正的JobClass,而是通过JobDetail来保存。注意,我们给scheduler传入了一个JobDetail实例,而且这个JobDetail实例只是简单提供了类名来引用被执行的Job。每次scheduler执行这个任务时,它就创建这个类的新实例,然后调用该实例的execute(..)方法。Job不必担心线程安全性,因为同一时刻仅有一个线程去执行给定Job类的实例,甚至是并发执行同一Job也是如此。推断:Job类必须有一个无参数的构造函数Job类中定义的成员数据失去意义,因为这些成员数据值在每次执行的时候被“清空”了。14JobFactoryJobFactory控制job的实例化JobnewJob(TriggerFiredBundlebundle)throwsSchedulerException;默认的JobFactory是org.quartz.simpl.SimpleJobFactory,缺省的JobFactory只是简单地对Job类调用newInstance()方法。设置JobFactory:Scheduler.setJobFactory(factory)配置quartz.properties的org.quartz.scheduler.jobFactory.class属性设置jobFactory的类型15JobDataMapJobDataMap被用来保存一系列的(序列化的)对象,这些对象在Job执行时可以得到。JobDataMap是JavaMap接口的一个实现,而且还增加了一些存储和读取主类型数据的便捷方法。JobDetail.getJobDataMap().put(jobSays,HelloWorld!);JobExecutionContext.getJobDetail().getJobDataMap();Trigger.getJobDataMap();JobExecutionContext.getMergedJobDataMap();16StatefulJob有状态任务任务在执行任务过程中,任何对JobDataMap所作的更改都将丢失而且任务下次执行时也无法看到。StatefulJob在任务的每次执行之后重新存储JobDataMapJobvs.StatefulJobJobDataMap在每次执行之后重新持久化到JobStore中。两个或多个有状态的JobDetail实例不能并发执行。17TriggerTrigger对象被用来触发jobs的执行。你希望将任务纳入到进度,要实例化一个Trigger并且“调整”它的属性以满足你想要的进度安排。Triggers也有一个JobDataMap与之关联,这非常有利于向触发器所触发的Job传递参数。Quartz打包了很多不同类型的Trigger,但最常用的Trigger类是SimpleTrigger和CronTrigger。18SimpleTriggerSimpleTrigger用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。如果你想让触发器在2010年1月11日,上午11:23:54秒执行,然后每个隔10秒钟重复执行一次,并且这样重复5次。那么SimpleTrigger就可以满足你的要求。publicSimpleTrigger(Stringname,Stringgroup,StringjobName,StringjobGroup,DatestartTime,DateendTime,intrepeatCount,longrepeatInterval);19CronTrigger如果你需要像日历那样按日程来触发任务,而不是像SimpleTrigger那样每隔特定的间隔时间触发,CronTriggers通常比SimpleTrigger更有用。使用CronTrigger,你可以指定诸如“每个周五中午”,或者“每个工作日的9:30”或者“从每个周一、周三、周五的上午9:00到上午10:00之间每隔五分钟”这样日程安排来触发。甚至,象SimpleTrigger一样,CronTrigger也有一个startTime以指定日程从什么时候开始,也有一个(可选的)endTime以指定何时日程不再继续。publicCronTrigger(Stringname,Stringgroup,StringjobName,StringjobGroup,DatestartTime,DateendTime,StringcronExpressio