




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Quartz 项目应用笔记 Quartz 是一个强大的企业级 Schedule 工具,也是目前最好的开源 Schedule 工具,最近因为项目的需要,简单的用到了 Quartz 的一些功能,对项目中使用 Quartz 的一些问题做简单的记录。在 Quartz 的应用中,我们用到了以下的一些东西,ScheduleFactory, Scheduler, Job, JobDetail, Trigger,简单说明一下他们的用途。SchedulerFactory 是 Scheduler 的工厂,我们可以从中获得受工厂管理的 Scheduler 对象。SchedulerFactory scheduleFactory = new StdSchedulerFactory();Scheduler scheduler = scheduleFactory.getScheduler();Scheduler 是一个计划集,其中可以包含多个 JobDetail 和 Trigger 组成的计划任务。我们可以从 SchedulerFactory 中取得 Scheduler。接口Job是每个业务上需要执行的任务需要实现的接口,该接口只有一个方法:public interface Job public void execute(JobExecutionContext context) throws JobExecutionException;我们可以在里面定义我们的 Job 执行逻辑,比如清除过期数据,更新缓存等。JobDetail描述了一个任务具体的信息,比如名称,组名等等。JobDetail jobDetail = new JobDetail(SayHelloWorldJob, Scheduler.DEFAULT_GROUP, SayHelloWorldJob.class);在上面的构造方法中,第一个是任务的名称,第二个是组名,第三个就是实际当任务需要执行的回调类。Trigger顾名思义就是触发器,Quartz有个很好的想法就是分离了任务和任务执行的条件。Trigger就是控制任务执行条件的类,当Trigger认为执行条件满足的时刻,Trigger会通知相关的Job去执行。分离的好处是:1.你可以为某个Job关联多个Trigger,其中任何一个条件满足都可以触发job执行,这样可以完成一些组合的高级触发条件2.当Trigger失效后(比如:一个永远都不能满足的条件),你不必去声明一个新的job,代替的是你可以为job关联一个新的Trigger让job可以继续执行。目前的Quartz实现中,存在两种Trigger,SimpleTrigger和CronTrigger,SimpleTrigger用来完成一些比如固定时间执行的任务,比如:从现在开始1分钟后等等;而CronTrigger(没错,和unix的cron进程的含意一样)用来执行calendar-like的任务,比如:每周五下午3:00,每月最后一天等等。在我们项目中,都是一些固定时间的 Job,所以只用到了 SimpleTrigger。Trigger trigger = new SimpleTrigger(SayHelloWorldJobTrigger,Scheduler.DEFAULT_GROUP,new Date(),null,0,0L);这个构造方法中,第一个是Trigger的名称,第二个是Trigger的组名,第三个是任务开始时间,第四个是结束时间,第五个是重复次数(使用SimpleTrigger.REPEAT_INDEFINITELY常量表示无限次),最后一个是重复周期(单位是毫秒),那么这样就创建了一个立刻并只执行一次的任务。但我们定义好了 JobDetail,Job,和 Trigger 后,就可以开始 Schedule 一个 Job 了。scheduler.scheduleJob(jobDetail, trigger);这条语句就是把job和Trigger关联,这样当Trigger认为应该触发的时候就会调用(实际上是Scheduler调用)job.execute方法了。scheduler.start();千万别忘了加上上面的语句,这条语句通知Quartz使安排的计划生效。关于execute方法的参数JobExecutionContextJobExecutionContext就和很多Context结尾的类功能一样,提供的运行时刻的上下文环境,JobExecutionContext中有Scheduler,JobDetail,Trigger等很多对象的引用,从而当你在execute方法内部须需要这些对象的时刻提供的便利。在项目中,我们把需要执行的 Job 相对应的一些信息放在 JobExecutionContext 中,在 Job 执行的时候可以调用。jobDetail.getJobDataMap().put(userid, id);在 Job 中,我们可以拿到相关的 Context 信息:jobExecutionContext.getJobDetail().getJobDataMap().getInt(userid);JobDetail和Trigger的name和groupScheduler实例对应了很多job和trigger的实例,为了方便的区分,Quartz使用name和group这两个特性,正如你想向的一样,同一个group下不能有两个相同name的JobDetail,Trigger同理,同一个Scheduler下不能有两个相同group的JobDetail,Trigger同理,JobDetail和Trigger的完全限定名为:group + name为了让服务器重启以后,我们的 Scheduler 信息仍然不丢失,我们通常采用数据库持久化 Scheduler 的信息。DBScript 在 Quartz 的下载包中的:quartz-1.6.0docsdbTables 下,选择自己使用的 DB 相应的 Script 导入数据库就可以了。在应用中,我们需要配置一个 perties 才能正常使用 DB。我们可以在 quartz-1.6.0examplesexample10 中找到该文件的样例,稍作一些修改,就可以放到自己项目源码的根目录下使用了。设置 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX 即可启用基于 JDBC 的 Quartz 信息持久化。根据项目情况设置以下配置信息:org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.useProperties = falseorg.quartz.jobStore.dataSource = myDSorg.quartz.jobStore.tablePrefix = QRTZ_org.quartz.jobStore.isClustered = falseorg.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driverorg.quartz.dataSource.myDS.URL = jdbc:mysql:/localhost:3306/myapplicationorg.quartz.dataSource.myDS.user = rootorg.quartz.dataSource.myDS.password =org.quartz.dataSource.myDS.maxConnections = 5但是光设置了 Database 不够,我们还需要在 Application 启动的时候自动启动 Scheduler 才行,我们只需要简单的写一个 Servlet 的 Listener 并在 web.xml 中声明该 Listener ,在 Servlet 容易启动的时候,Scheduler 就开始自动执行。public class ScheduleStartListener implements ServletContextListener public void contextInitialized(ServletContextEvent servletContextEvent) try scheduleFactory.getScheduler().start(); catch (SchedulerException e) / write log public void contextDestroyed(ServletContextEvent servletContextEvent) try scheduleFactory.getScheduler().shutdown(); catch (SchedulerException e) / write log 在 web.xml 里面加入以下配置: org.agilejava.scheduler.ScheduleStartListener以上简单的记录了在项目中关于 Quartz 的一些应用,如果有什么新的使用心得,会在后面继续加入的。对quartz的总结 关键字: Spring spring quartz 学习心得 Quartz 是一个强大的企业级 Schedule 工具,也是目前最好的开源 Schedule 工具。Spring中也集成了quartz的应用,下面就讲一下如何在spring中使用quartz。spring的配置:xml 代码1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 1000 21. 22. 23. 3000 24. 25. 26. 27. 28. 29. 30. 31. 0 0 */1 * * ? 32. 33. 34. Job:org.quartz.Job是一个接口,只定义了void execute(JobExecutionContext context)throws JobExecutionException;一个方法。当定时任务被触发后,系统会自动调用实现了该接口的方法。在spring中,org.springframework.scheduling.quartz.QuartzJobBean对其进行了封装,使用了Template Method模式。主要是为了在使用jobDataMap时更加方便。QuartzJobBean有两个方法,public final void execute(JobExecutionContext context) throws JobExecutionExceptionJob接口中定义的,spring在该方法里进行了些处理,将jobDataMap中的值注入到该Job的实现者中protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException这是一个抽象方法,用户在扩展了QuartzJobBean后,要自己实现该方法,在其中添加相应的业务逻辑JobDetail:JobDetail描述了一个任务具体的信息。在Spring中,JobDetailBean对JobDetail进行了封装(继承了JobDetail)。private String name;/名称private String group = Scheduler.DEFAULT_GROUP;/组private String description;/描述private Class jobClass;/定时任务触发时,回调的class,该class要实现Job接口或继承QuartzJobBeanprivate JobDataMap jobDataMap;/该任务存储的数据,在回调的时候也可以使用private boolean volatility = false;/是否持久化到org.quartz.spi.JobStore中private boolean durability = false;/当该任务完成后,是否还在JobStore中继续保留该任务private boolean shouldRecover = false;/当系统重新启动后,是否再次执行该任务对于jobDataMap,它是是一个封装过的Map,使用方法同Map,如jobDetailBean.getJobDataMap().put(target,value);如果使用了QuartzJobBean,在使用jobDetailBean时,可将target的值设成QuartzJobBean的子类的属性名称,这样,在定时触发时,spring会自动将与target对应的value值注入到QuartzJobBean的子类中去。如。java 代码1. 2.public class ReminderManager extends QuartzJobBean 3. private String reminderStr = ; 4. 5. 6.jobDetailBean.getJobDataMap().put(reminderStr,abcdefg); 7. 这样当该任务被触发后,在ReminderManager中,reminderStr的值就会被注入为abcdefg。Trigger:trigger就是触发器。Quartz有个很好的想法就是分离了任务和任务执行的条件。Trigger就是控制任务执行条件的类,当Trigger认为执行条件满足的时刻,Trigger会通知相关的Job去执行。分离的好处是:1.你可以为某个Job关联多个Trigger,其中任何一个条件满足都可以触发job执行,这样可以完成一些组合的高级触发条件2.当Trigger失效后(比如:一个永远都不能满足的条件),你不必去声明一个新的job,代替的是你可以为job关联一个新的Trigger让job可以继续执行。目前的Quartz实现中,存在两种Trigger,SimpleTrigger和CronTrigger,在spring中分别用SimpleTriggerBean和CronTriggerBean对其进行封装。SimpleTrigger是简单触发器,如从某日到某日,每个一定时间进行一次提醒,在这段时间内进行多少次提醒;CronTrigger是复杂触发器,用来执行calendar-like的任务,可设定一些复杂的触发规则,如每年的x月的第y个星期五,或是每个星期天的几点进行提醒。后面附加一个日常语义与cronTrigger的转化Triggerprivate String name;/名称private String group = Scheduler.DEFAULT_GROUP;/组private String jobName;/所关联的jobDetail的名称private String jobGroup = Scheduler.DEFAULT_GROUP;/所关联的jobDetail的组private String description;/描述private JobDataMap jobDataMap;/该触发器存储的数据,在回调的时候也可以使用private boolean volatility = false;/是否持久化到org.quartz.spi.JobStore中SimpleTriggerprivate Date startTime = null;/开始日期private Date endTime = null;/结束日期private Date nextFireTime = null;/下次的触发时间private Date previousFireTime = null;/上次的触发时间private int repeatCount = 0;/重复次数private long repeatInterval = 0;/重复间隔private int timesTriggered = 0;/已触发的次数SimpleTriggerBeanprivate JobDetail jobDetail;/所关联的JobDetail,方便在配置文件中使用CornTriggerprivate CronExpression cronEx = null;/触发条件表达式,它有一个String型的setterprivate Date startTime = null;/开始日期private Date endTime = null;/结束日期private Date nextFireTime = null;/下次的触发时间private Date previousFireTime = null;/上次的触发时间private transient TimeZone timeZone = null;/所在时区CronTriggerBeanprivate JobDetail jobDetail;/所关联的JobDetail,方便在配置文件中使用Scheduler的常用方法添加一个定时任务:Date scheduleJob(JobDetail jobDetail,Trigger trigger)修改一个定时任务,主要是更改trigger:Date rescheduleJob(String triggerName, String groupName, Trigger newTrigger)删除一个定时任务,同时也会将于该jobDetail关联的trigger一并删除:boolean deleteJob(String jobName,String jobGroup)取得所有的jobDetail组String getJobGroupNames() 取得某个group下的所有的jobDetailString getJobNames(String groupName)取得指定的jobDetailJobDetail getJobDetail(String jobName, String jobGroup)取得指定的jobDetail的所有的TriggerTrigger getTriggersOfJob(String jobName, String groupName)取得指定的TriggerTrigger getTrigger(String triggerName, String triggerGroup)Quartz的存储:Quartz默认的是使用RAM存储所有的信息,但是这样的话,当我们重启服务器后,之前的所有的定时任务就全消失了。为了让服务器重启以后,我们的定时任务仍不丢失,我们可采用数据库持久化定时任务。首先要先建立数据库,在quartz-1.6.0docsdbTables下,选择自己使用的数据库的sql脚本,建立相应的数据库表。在WEB-INF下加一个perties。我们可以在 quartz-1.6.0examplesexample10 中找到该文件的样例org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX #表明使用JDBC进行持久化org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.useProperties = falseorg.quartz.jobStore.dataSource = myDSorg.quartz.jobStore.tablePrefix = QRTZ_ #该值尽量不要改动,如改动,还要相应的修改sql脚本org.quartz.jobStore.isClustered = falseorg.quartz.dataSource.myDS.driver = net.sourceforge.jtds.jdbc.Driverorg.quartz.dataSource.myDS.URL = jdbc:jtds:sqlserver:/01:1433/Northwind;autoReconnect=trueorg.quartz.dataSource.myDS.user = saorg.quartz.dataSource.myDS.password =org.quartz.dataSource.myDS.maxConnections = 5日常语义与cronTrigger的转化,以下setter,getter省略java 代码1.public class TDateRange 2. private int startType = 2;/开始类型。默认的使用2表示使用开始日期 3. private Date startDate = new Date();/开始日期 4. private int endType = 0;/结束类型。0表示无结束时间;1表示重复n次后结束;2表示使用结束日期 5. private Date endDate = new Date();/结束日期 6. private int occurrences;/执行次数 7. 8.public class TFrequency 9. /0:无重复提醒 10. /1:每every 11. /2:每个工作日detail=1,2,3,4,5 12. /3:每every周后的星期detail日 13. /4:每every月的detail日 14. /5:每every月的第num1个星期num2 15. /6:每年num1月num2日 16. /7:每年every月的第num1个月的星期num2 17. private int type = 0;/频率类型 18. private int every = 0; 19. private String detail = ; 20. private String num1 = ; 21. private String num2 = ; 22. 23. 24.private String formatQuartzString() 25. String quartzStr = ; 26. tiggernote=; 27. /秒 分 时 28. quartzStr = 0 +this.dateRange.getStartDate().getMinutes()+ +this.dateRange.getStartDate().getHours()+ ; 29. switch(this.frequency.getType() 30. case 0:/无重复提醒 31. quartzStr += this.dateRange.getStartDate().getDate()+ +(this.dateRange.getStartDate().getMonth()+1)+ ? +(this.dateRange.getStartDate().getYear()+1900); 32. tiggernote+=起始时间:+quartzStr; 33. break; 34. case 1:/每XX天提醒 35. quartzStr += */+this.frequency.getEvery()+ * ? ; 36. tiggernote+=每+this.frequency.getEvery()+提醒; 37. break; 38. case 2:/每个工作日detail=1,2,3,4,5 39. /quartzStr += ? * 2-6; 40. quartzStr =0 */1 * * * ?; /测试 41. tiggernote+=每个工作日1,2,3,4,5提醒; 42. break; 43. case 3:/每every周后的星期detail日 44. quartzStr += ? * +this.frequency.getDetail()+/+this.frequency.getEvery(); 45. tiggernote+=每+this.frequency.getEvery()+周星期+this.frequency.getDetail()+日; 46. break; 47. case 4:/每every个月的detail日 48. quartzStr += this.frequency.getDetail()+ */+this.frequency.getEvery()+ ?; 49. tiggernote+=每+this.frequency.getEvery()+月+this.frequency.getDetail()+日; 50. break; 51. case 5:/每every个月的第num1个星期num2 52. quartzStr += ? */+this.frequency.getEvery()+ +this.frequency.getNum2(); 53. /星期 54. if(Integer.valueOf(this.frequency.getNum1().intValue()0) 55. quartzStr += #+this.frequency.getNum1(); 56. tiggernote+=每+this.frequency.getEvery()+月第+this.frequency.getNum1()+个星期+this.frequency.getNum2()+日; 57. else 58. quartzStr += L; 59. tiggernote+=每+this.frequency.getEvery()+月星期+this.frequency.getNum2(); 60. 61. break; 62. case 6:/每年num1月num2日 63. quartzStr += this.frequency.getNum2(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 本科html考试试题及答案
- 北京高中数学考试卷子及答案
- N6-Allylamino-carbonothioyl-lysine-13C6-15N2-生命科学试剂-MCE
- 电焊工焊接知识培训总结课件
- hu3S193-生命科学试剂-MCE
- 保险金融资格考试题库及答案
- 新解读《GB-T 2999-2016耐火材料 颗粒体积密度试验方法》
- 高楼居民安全知识培训课件
- 电炉操作知识培训课件
- 电源线缆安全知识培训课件
- 新生儿病房护理安全管理
- 瑞雪迎春春节家宴主题说明书
- 军用车修理知识培训课件
- 乘客遗失物品处理课件
- 2025年云南省中考物理真题(含答案)
- 医院保卫科岗位竞聘工作汇报
- 医院科室停电应急预案
- 2025年教育学家教学理论考试试题及答案解析
- 2025年职业指导师中级专业能力试卷:就业指导实务操作技能
- 保健公司客户服务流程规定
- 项目初步验收汇报
评论
0/150
提交评论