Quartz框架快速入门.docx
- 文档编号:15558732
- 上传时间:2023-07-05
- 格式:DOCX
- 页数:26
- 大小:63.50KB
Quartz框架快速入门.docx
《Quartz框架快速入门.docx》由会员分享,可在线阅读,更多相关《Quartz框架快速入门.docx(26页珍藏版)》请在冰点文库上搜索。
Quartz框架快速入门
Quartz快速入门一
创建一个Java工程,引入几个JAR到工程中才能成功构建它们。
首先,你需要Quartz的二进制版本,包的名字是quartz-
Quartz还需要几个第三方库;这依赖于你要用到框架的什么功能而定,CommonsDigester库可以在
如果出现java.lang.NoClassDefFoundError:
javax/transaction/UserTransaction的错误,解决办法是:
引入jta.jar包,这个包在quartz-1.6.0/lib/build下。
·创建一个QuartzJob类
每一个QuartzJob必须有一个实现了org.quartz.Job接口的具体类。
这个接口仅有一个要你在Job中实现的方法,execute(),方法execute()的原型如下:
publicvoidexecute(JobExecutionContextcontext)throwsJobExecutionException;
当Quartz调度器确定到时间要激发一个Job的时候,它就会生成一个 Job实例,并调用这个实例的execute()方法。
调度器只管调用execute()方法,而不关心执行的结果,除了在作业执行中出问题抛出的org.quartz.JobExecutionException异常。
下面是我们的第一个Quartzjob,它被设计来扫描一个目录中的文并显示文件的详细信息。
packagecom.vista.quartz;
importjava.io.File;
importjava.io.FileFilter;
importjava.util.Date;
importmons.logging.Log;
importmons.logging.LogFactory;
importorg.quartz.Job;
importorg.quartz.JobDataMap;
importorg.quartz.JobDetail;
importorg.quartz.JobExecutionContext;
importorg.quartz.JobExecutionException;
publicclassScanDirectoryJobimplementsJob
{
staticLoglogger=LogFactory.getLog(ScanDirectoryJob.class);//日志记录器
publicvoidexecute(JobExecutionContextcontext)throwsJobExecutionException
{
//Everyjobhasitsownjobdetail
JobDetailjobDetail=context.getJobDetail();
//Thenameisdefinedinthejobdefinition
StringjobName=jobDetail.getName();//任务名称
//Logthetimethejobstarted
logger.info(jobName+"firedat"+newDate());//记录任务开始执行的时间
//Thedirectorytoscanisstoredinthejobmap
JobDataMapdataMap=jobDetail.getJobDataMap();//任务所配置的数据映射表
StringdirName=dataMap.getString("SCAN_DIR");//获取要扫描的目录
//Validatetherequiredinput
if(dirName==null)
{//所需要的扫描目录没有提供
thrownewJobExecutionException("Directorynotconfigured");
}
//Makesurethedirectoryexists
Filedir=newFile(dirName);
if(!
dir.exists())
{//提供的是错误目录
thrownewJobExecutionException("InvalidDir"+dirName);
}
//UseFileFiltertogetonlyXMLfiles
FileFilterfilter=newFileExtensionFileFilter(".xml");
//只统计xml文件
File[]files=dir.listFiles(filter);
if(files==null||files.length<=0)
{//目录下没有xml文件
logger.info("NoXMLfilesfoundin"+dir);
//Returnsincetherewerenofiles
return;
}
//ThenumberofXMLfiles
intsize=files.length;
//Iteratethroughthefilesfound
for(inti=0;i { Filefile=files[i]; //Logsomethinginterestingabouteachfile. FileaFile=file.getAbsoluteFile(); longfileSize=file.length(); Stringmsg=aFile+"-Size: "+fileSize; logger.info(msg);//记录下文件的路径和大小 } } } 当Quartz调用execute()方法,会传递一个org.quartz.JobExecutionContext上下文变量,里面封装有Quartz的运行时环境和当前正执行的Job。 通过JobexecutionContext,你可以访问到调度器的信息,作业和作业上的触发器的信息,还有更多更多的信息。 在代码中,JobExecutionContext被用来访问org.quartz.JobDetail类,JobDetail类持有Job的详细信息,包括为Job实例指定的名称,Job所属组,Job是否被持久化(易失性),和许多其他感兴趣的属性。 JobDetail又持有一个指向org.quartz.JobDataMap的引用。 JobDataMap中有为指定Job配置的自定义属性。 例如,在代码中我们从JobDataMap中获得欲扫描的目录名,我们可以在ScanDirectoryJob中硬编码这个目录名,但是这样的话我们难以重用这个Job来扫描别的目录了。 在后面你将会看到目录是如何配置到JobDataMap的。 execute()方法中剩下的就是标准Java代码了: 获得目录名并创建一个java.io.File对象。 它还对目录名作为简单的校验,确保是一个有效且存在的目录。 接着调用File对象的listFiles()方法得到目录下的文件。 还创建了一个java.io.FileFilter对象作为参数传递给listFiles()方法。 org.quartzbook.cavaness.FileExtensionFileFilter实现了java.io.FileFilter接口,它的作用是过滤掉目录仅返回XML文件。 默认情况下,listFiles()方法是返回目录中所有内容,不管是文件还是子目录,所以我们必须过滤一下,因为我们只对XML文件感兴趣。 FileExtensionFileFilter被用来屏蔽名称中不含字符串“.xml”的文件。 它还屏蔽了子目录--这些子目录原本会让listFiles()方法正常返回。 过滤器提供了一种很便利的方式选择性的向你的Quartz作业提供它能接受的作为输入的文件 packagecom.vista.quartz; importjava.io.File; importjava.io.FileFilter; publicclassFileExtensionFileFilterimplementsFileFilter { privateStringextension;//文件后缀 publicFileExtensionFileFilter(Stringextension) { this.extension=extension; } publicbooleanaccept(Filefile) {//只接受指定后缀的文件 //Lowercasethefilenameforeasiercomparison StringlCaseFilename=file.getName().toLowerCase();//小写化 return(file.isFile()&&(lCaseFilename.indexOf(extension)>0))? true: false; } } 到目前为止,我们已经创建了一个Quartzjob,但还没有决定怎么处置它--明显地,我们需以某种方式为这个Job设置一个运行时间表。 时间表可以是一次性的事件,或者我们可能会安装它在除周日之外的每个午夜执行。 你即刻将会看到,QuartzSchduler是框架的心脏与灵魂。 所有的Job都通过Schduler注册;必要时,Scheduler也会创建Job类的实例,并执行实例的execute()方法。 ·编程式安排一个QuartzJob 所有的要Quartz来执行的作业必须通过调度器来注册。 大多情况下,这会在调度器启动前做好。 正如前面说过,这一操作也提供了声明式与编程式两种实现途径的选择。 因为每一个Job都必须用Scheduler来注册,所以先定义一个JobDetail,并关联到这个Scheduler实例。 下面的程序提供了一个理解如何编程式安排一个Job很好的例子。 代码首先调用createScheduler()方法从Scheduler工厂获取一个Scheduler的实例。 得到Scheduler实例之后,把它传递给schedulerJob()方法,由它把Job同Scheduler进行关联。 首先,创建了我们想要运行的Job的JobDetail对象。 JobDetail构造器的参数中包含指派给Job的名称,逻辑组名,和实现org.quartz.Job接口的全限类名称。 我们可以使用JobDetail的别的构造器。 在前面有说过,JobDetail扮演着某一Job定义的角色。 它带有Job实例的属性,能在运行时被所关联的Job访问到。 其中在使用JobDetail时,的一个最重要的东西就是JobDataMap,它被用来存放Job实例的状态和参数。 在代码中,待扫描的目录名称就是通过scheduleJob()方法存入到JobDataMap中的。 Job只是一个部分而已。 注意我们没有在JobDetail对象中为Job设定执行日期和次数。 这是QuartzTrigger该做的事。 顾名思义,Trigger的责任就是触发一个Job去执行。 当用Scheduler注册一个Job的时候要创建一个Trigger与这个Job相关联。 Quartz提供了四种类型的Trigger,但其中两种是最为常用的,它们就是在下面要用到的SimpleTrigger和CronTrigger. SimpleTrigger是两个之中简单的那个,它主要用来激发单事件的Job,Trigger在指定时间激发,并重复n次--两次激发时间之间的延时为m,然后结束作业。 CronTrigger非常复杂且强大。 它是基于通用的公历,当需要用一种较复杂的时间表去执行一个Job时用到。 例如,四月至九月的每个星期一、星期三、或星期五的午夜。 为更简单的使用Trigger,Quartz包含了一个工具类,叫做org.quartz.TriggerUtils.TriggerUtils提供了许多便捷的方法简化了构造和配置trigger.本文的例子中有用的就是TriggerUtils类;SimpleTrigger和CronTrigger会在后面用到。 正如你看到的那样,调用了TriggerUtils的方法makeSecondlyTrigger()来创建一个每10秒种激发一次的trigger(实际是由TriggerUtils生成了一个SimpleTrigger实例,但是我们的代码并不想知道这些)。 我们同样要给这个trigger实例一个名称并告诉它何时激发相应的Job;与之关联的Job会立即启动,因为由方法setStartTime()设定的是当前时间 packagecom.vista.quartz; importjava.util.Date; importmons.logging.Log; importmons.logging.LogFactory; importorg.quartz.JobDetail; importorg.quartz.Scheduler; importorg.quartz.SchedulerException; importorg.quartz.Trigger; importorg.quartz.TriggerUtils; importorg.quartz.impl.StdSchedulerFactory; publicclassSimpleScheduler { staticLoglogger=LogFactory.getLog(SimpleScheduler.class); publicstaticvoidmain(String[]args) { SimpleSchedulersimple=newSimpleScheduler(); try { //CreateaSchedulerandscheduletheJob Schedulerscheduler=simple.createScheduler(); simple.scheduleJob(scheduler); //StarttheSchedulerrunning scheduler.start(); logger.info("Schedulerstartedat"+newDate()); }catch(SchedulerExceptionex){ logger.error(ex); } } publicSchedulercreateScheduler()throwsSchedulerException {//创建调度器 returnStdSchedulerFactory.getDefaultScheduler(); } //CreateandScheduleaScanDirectoryJobwiththeScheduler privatevoidscheduleJob(Schedulerscheduler)throwsSchedulerException { //CreateaJobDetailfortheJob JobDetailjobDetail=newJobDetail("ScanDirectory",Scheduler.DEFAULT_GROUP,ScanDirectoryJob.class); //Configurethedirectorytoscan jobDetail.getJobDataMap().put("SCAN_DIR","D: \\Tomcat\\conf");//settheJobDataMapthatisassociatedwiththeJob. //Createatriggerthatfiresevery10seconds,forever Triggertrigger=TriggerUtils.makeSecondlyTrigger(10);//每10秒触发一次 trigger.setName("scanTrigger"); //Startthetriggerfiringfromnow trigger.setStartTime(newDate());//设置第一次触发时间 //Associatethetriggerwiththejobinthescheduler scheduler.scheduleJob(jobDetail,trigger); } } 假如你有不只一个个Job(你也许就是),你将需要为每一个Job创建各自的JobDetail。 每一个JobDetail必须通过scheduleJob()方法一一注册到Scheduler上。 而如果你想重用了一个Job类,让它产生多个实例运行,那么你需要为每个实例都创建一个JobDetail。 例如,假如你想重用ScanDirectoryJob让它检查两个不同的目录,你需要创建并注册两个JobDetail实例 packagecom.vista.quartz; importjava.util.Date; importmons.logging.Log; importmons.logging.LogFactory; importorg.quartz.JobDetail; importorg.quartz.Scheduler; importorg.quartz.SchedulerException; importorg.quartz.Trigger; importorg.quartz.TriggerUtils; importorg.quartz.impl.StdSchedulerFactory; publicclassSimpleScheduler { staticLoglogger=LogFactory.getLog(SimpleScheduler.class); publicstaticvoidmain(String[]args) { SimpleSchedulersimple=newSimpleScheduler(); try { //CreateaSchedulerandscheduletheJob Schedulerscheduler=simple.createScheduler(); //JobscanbescheduledafterSchedulerisrunning scheduler.start(); logger.info("Schedulerstartedat"+newDate()); //SchedulethefirstJob simple.scheduleJob(scheduler,"ScanDirectory1",ScanDirectoryJob.class,"D: \\conf1",10); //SchedulethesecondJob simple.scheduleJob(scheduler,"ScanDirectory2",ScanDirectoryJob.class,"D: \\conf2",15); } catch(SchedulerExceptionex) { logger.error(ex); } } publicSchedulercreateScheduler()throwsSchedulerException {//创建调度器 returnStdSchedulerFactory.getDefaultScheduler(); } privatevoidscheduleJob(Schedulerscheduler,StringjobName,ClassjobClass,StringscanDir,intscanInterval)throwsSchedulerException { //CreateaJobDetailfortheJob JobDetailjobDetail=newJobDetail(jobName,Scheduler.DEFAULT_GROUP,jobClass); //Configurethedirectorytoscan jobDetail.getJobDataMap().put("SCAN_DIR",scanDir); //Triggerthatrepeatsevery"scanInterval"secsforever Triggertrigger=TriggerUtils.makeSecondlyTrigger(scanInterval); trigger.setName(jobName+"-Trigger"); //Startthetriggerfiringfromnow trigger.setStartTime(newDate()); //Associatethetriggerwiththejobinthescheduler scheduler.scheduleJob(jobDetail,trigger); } } Quartz快速入门二 尽可能的用声明式处理软件配置,其次才考虑编程式的方式。 在上一篇《Quartz框架快速入门 (一)》中,如果我们要在Job启动之后改变它的执行时间和频度,必须去修改源代码重新编译。 这种方式只适用于小的例子程序,但是对于一个大且复杂的系统,这就成了一个问题了。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Quartz 框架 快速 入门