Timer, Quartz 和 Spring 实现作业调度
来源:互联网 发布:阿里云 关闭云盾 编辑:程序博客网 时间:2024/05/15 04:07
一、java.util.Timer
在Java中有一个任务处理类java.util.Timer,非常方便于处理由时间触发的事件任务,只需建立一个继承java.util.TimerTask的子类,重载父类的run()方法实现具体的任务,然后调用Timer的public void schedule(TimerTask task, long delay, long period)方法实现任务的调度。
但是这种方法只能实现简单的任务调度,不能满足任务调度时间比较复杂的需求。比如希望系统在每周的工作日的8:00时向系统用户给出一个提示,这种方法实现起来就困难了,还有更为复杂的任务调度时间要求。
二、Quartz
1、作业
实现 org.quartz.job 接口,实现接口方法 public void execute(JobExecutionContext context) throws JobExecutionException,在这个方法实现具体的作业任务。
代码例子:
execute 方法接受一个 JobExecutionContext 对象作为参数。这个对象提供了作业实例的运行时上下文。它提供了对调度器和触发器的访问,这两者协作来启动作业以及作业的 JobDetail 对象的执行。Quartz 通过把作业的状态放在 JobDetail 对象中并让 JobDetail 构造函数启动一个作业的实例,分离了作业的执行和作业周围的状态。JobDetail 对象储存作业的侦听器、群组、数据映射、描述以及作业的其他属性。
2、触发器
触发器可以实现对任务执行的调度。Quartz 提供了几种不同的触发器,复杂程度各不相同。
简单触发器:
public void task() throws SchedulerException { // Initiate a Schedule Factory SchedulerFactory schedulerFactory = new StdSchedulerFactory(); // Retrieve a scheduler from schedule factory Scheduler scheduler = schedulerFactory.getScheduler(); // current time long ctime = System.currentTimeMillis(); // Initiate JobDetail with job name, job group, and executable job class JobDetail jobDetail = new JobDetail("jobDetail-s1", "jobDetailGroup-s1", SimpleQuartzJob.class); // Initiate SimpleTrigger with its name and group name SimpleTrigger simpleTrigger = new SimpleTrigger("simpleTrigger", "triggerGroup-s1"); // set its start up time simpleTrigger.setStartTime(new Date(ctime)); // set the interval, how often the job should run (10 seconds here) simpleTrigger.setRepeatInterval(10000); // set the number of execution of this job, set to 10 times. // It will run 10 time and exhaust. simpleTrigger.setRepeatCount(100); // set the ending time of this job. // We set it for 60 seconds from its startup time here // Even if we set its repeat count to 10, // this will stop its process after 6 repeats as it gets it endtime by then. // simpleTrigger.setEndTime(new Date(ctime + 60000L)); // set priority of trigger. If not set, the default is 5 // simpleTrigger.setPriority(10); // schedule a job with JobDetail and Trigger scheduler.scheduleJob(jobDetail, simpleTrigger); // start the scheduler scheduler.start(); }
首先实例化一个 SchedulerFactory,获得调度器。创建 JobDetail 对象时,它的构造函数要接受一个 Job 作为参数。SimpleTrigger 是一个简单的触发器。在创建对象之后,设置几个基本属性以立即调度任务,然后每 10 秒重复一次,直到作业被执行 100 次。
Cron触发器
CronTrigger 支持比 SimpleTrigger 更具体强大的调度,实现起来却不是很复杂。CronTrigger基于 cron 表达式,支持类似日历的重复间隔更为复杂的调度时间上的要求。
Cron 表达式包括以下 7 个字段:
- 秒
- 分
- 小时
- 月内日期
- 月
- 周内日期
- 年(可选字段)
Cron 触发器利用一系列特殊字符,如下所示:
- 反斜线(/)字符表示增量值。例如,在秒字段中“5/15”代表从第 5 秒开始,每 15 秒一次。
- 问号(?)字符和字母 L 字符只有在月内日期和周内日期字段中可用。问号表示这个字段不包含具体值。所以,如果指定月内日期,可以在周内日期字段中插入“?”,表示周内日期值无关紧要。字母 L 字符是 last 的缩写。放在月内日期字段中,表示安排在当月最后一天执行。在周内日期字段中,如果“L”单独存在,就等于“7”,否则代表当月内周内日期的最后一个实例。所以“0L”表示安排在当月的最后一个星期日执行。
- 在月内日期字段中的字母(W)字符把执行安排在最靠近指定值的工作日。把“1W”放在月内日期字段中,表示把执行安排在当月的第一个工作日内。
- 井号(#)字符为给定月份指定具体的工作日实例。把“MON#2”放在周内日期字段中,表示把任务安排在当月的第二个星期一。
- 星号(*)字符是通配字符,表示该字段可以接受任何可能的值。
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 * ?" 每月15日上午10:15触发
"0 15 10 L * ?" 每月最后一日的上午10:15触发
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
所有这些定义看起来可能有些吓人,但是只要几分钟练习之后,cron 表达式就会显得十分简单。
下面的代码显示了 CronTrigger 的一个示例。请注意 SchedulerFactory、Scheduler 和 JobDetail 的实例化,与 SimpleTrigger 示例中的实例化是相同的。在这个示例中,只是修改了触发器。这里指定的 cron 表达式(“0/5 * * * * ?”)安排任务每 5 秒执行一次。
public void task() throws SchedulerException { // Initiate a Schedule Factory SchedulerFactory schedulerFactory = new StdSchedulerFactory(); // Retrieve a scheduler from schedule factory Scheduler scheduler = schedulerFactory.getScheduler(); // current time long ctime = System.currentTimeMillis(); // Initiate JobDetail with job name, job group, and executable job class JobDetail jobDetail = new JobDetail("jobDetail2", "jobDetailGroup2", SimpleQuartzJob.class); // Initiate CronTrigger with its name and group name CronTrigger cronTrigger = new CronTrigger("cronTrigger", "triggerGroup2"); try { // setup CronExpression CronExpression cexp = new CronExpression("0/5 * * * * ?"); // Assign the CronExpression to CronTrigger cronTrigger.setCronExpression(cexp); } catch (Exception e) { e.printStackTrace(); } // schedule a job with JobDetail and Trigger scheduler.scheduleJob(jobDetail, cronTrigger); // start the scheduler scheduler.start(); }
三、Spring + Quartzspring对Java的Timer类和Quartz都提供了一个抽象层,使用我们可以更方便地使用它们。1、spring与Timer的集成 首先是一个定时器任务public class EmailReportTask extends TimerTask { public EmailReportTask() { } public void run() { courseService.sendCourseEnrollmentReport(); } private CourseService courseService; public void setCourseService(CourseService courseService) { this.courseService = courseService; }}spring配置文件中配置EmailReportTask
- <bean id="reportTimerTask"
- class="com.springinaction.training.schedule.EmailReportTask">
- <property name="courseService">
- <ref bean="courseService"/>
- </property>
- </bean>
调度定时器任务xml 代码启动定时器xml 代码
- <bean id="scheduledReportTask"
- class="org.springframework.scheduling.timer.ScheduledTimerTask">
- <property name="timerTask">
- <ref bean="reportTimerTask"/>
- property>
- <property name="period">
- <value>86400000<value>
- property>
- <property name="delay">
- <value>32000value>
- property>
- bean>
- <bean class="org.springframework.scheduling.timer.TimerFactoryBean">
- <property name="scheduledTimerTasks">
- <list>
- <ref bean="scheduledReportTask"/>
- list>
- property>
- bean>
2、spring与Quartz的集成
创建一个工作
- public class EmailReportJob extends QuartzJobBean {
- public EmailReportJob() {
- }
- protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
- courseService.sendCourseEnrollmentReport();
- }
- private CourseService courseService;
- public void setCourseService(CourseService courseService) {
- this.courseService = courseService;
- }
- }
在spring配置文件的配置EmailReportJob
- <bean id="reportJob"
- class="org.springframework.scheduling.quartz.JobDetailBean">
- <property name="jobClass">
- <value>com.springinaction.training.schedule.EmailReportJobvalue>
- property>
- <property name="jobDataAsMap">
- <map>
- <entry key="courseService">
- <ref bean="courseService"/>
- entry>
- map>
- property>
- bean>
调度工作
和quartz对应,Spirng提供了两个触发器SimpleTriggerBean和CronTriggerBean使用SimpleTriggerBean触发器
使用CronTriggerBean触发器
系统会在每分钟的0秒执行调度任务。
- Timer, Quartz 和 Spring 实现作业调度
- Timer, Quartz 和 Spring 实现作业调度
- Spring联姻Quartz实现作业调度
- Spring+Quartz 实现自动作业调度
- quartz 实现作业调度
- Timer和Quartz任务调度
- Spring + Quartz 作业调度框架
- spring 使用xml配置文件实现quartz作业调度
- Spring整合Quartz 2.2实现作业动态调度
- Spring调度 Quartz实现
- Java作业调度/定时任务 Spring和Quartz整合
- Java作业调度/定时任务 Spring和Quartz整合
- spring quartz、JDK timer 定时调度
- 使用quartz实现作业调度
- Jfinal+quartz实现作业调度
- Quartz.NET 实现作业调度
- 用Quartz实现作业调度
- Jfinal+quartz实现作业调度
- firefox margin-top失效的原因与解决办法
- blog,i am coming
- js 刷新页面 用 location.reload() 和 location.replace()
- delphi中的DBGRid鼠标滚动事件
- 昆明移动大量采用深圳如通电话销售系统提高销售效率
- Timer, Quartz 和 Spring 实现作业调度
- Css实现表格奇偶行不同色
- linux syslog
- TotalCommander中不能打开LNK快捷方式的解决方法
- static修饰符
- 3G无线宽带上网卡测试
- 《数据手袋》将实现复杂计算公式。
- 文档视图结构解析
- CFileDialog打开多个文件