在项目中有一个需求,需要灵活配置调度任务时间,并能自由启动或停止调度。
有关调度的实现我就第一就想到了Quartz这个开源调度组件,因为很多项目使用过,Spring结合Quartz静态配置调度任务时间,非常easy。比如:每天凌晨几点定时运行一个程序,这只要在工程中的spring配置文件中配置好spring整合quartz的几个属性就好。
Spring配置文件
Xml代码
这种配置就是对quartz的一种简单的使用了,调度任务会在spring启动的时候加载到内存中,按照cronTrigger中定义的 cronExpression定义的时间按时触发调度任务。但是这是quartz使用“内存”方式的一种配置,也比较常见,当然对于不使用spring的项目,也可以单独整合quartz。方法也比较简单,可以从quartz的doc中找到配置方式,或者看一下《Quartz Job Scheduling Framework 》。
但是对于想持久化调度任务的状态,并且灵活调整调度时间的方式来说,上面的内存方式就不能满足要求了,正如本文开始我遇到的情况,需要采用数据库方式集成 Quartz,这部分集成其实在《Quartz Job Scheduling Framework 》中也有较为详细的介绍,当然doc文档中也有,但是缺乏和spring集成的实例。
一、需要构建Quartz数据库表,建表脚本在Quartz发行包的docs\dbTables目录,里面有各种数据库建表脚本,例子中采用的Quartz 2.2.1版本,使用H2内存数据库,执行了Quartz发行包的docs\dbTables\tables_h2.sql建表。
二、建立Maven project,完成后目录如下
三、配置applicationContext.xml文件
Xml代码 <?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
这里只是配置了数据库连接dataSource,为了简单方便,我使用H2内存数据库,执行tables_h2.sql创建quartz数据库表,还没有涉及到quartz有关配置,下面且听我慢慢道来。
四、实现动态定时任务
什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。
这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现
Xml代码
中cronExpression是关键,如果可以动态设置cronExpression的值,就可以顺利解决问题了。这样我们就不能直接使用org.springframework.scheduling.quartz.CronTriggerFactoryBean,需要自己实现一个动态调度服务类,在其中构建CronTrigger或SimpleTrigger,动态配置时间。
动态调度服务接口:
Java代码 package com.sundoctor.quartz.service;
import java.util.Date;
import org.quartz.CronExpression;
public interface SchedulerService {
/**
* 根据 Quartz Cron Expression 调试任务
*
* @param cronExpression
* Quartz Cron 表达式,如 "0/10 * * ? * * *"等
*/
void schedule(String cronExpression);
/**
* 根据 Quartz Cron Expression 调试任务
*
* @param name
* Quartz CronTrigger名称
* @param cronExpression
* Quartz Cron 表达式,如 "0/10 * * ? * * *"等
*/
void schedule(String name, String cronExpression);
/**
* 根据 Quartz Cron Expression 调试任务
*
* @param name
* Quartz CronTrigger名称
* @param group
* Quartz CronTrigger组
* @param cronExpression
* Quartz Cron 表达式,如 "0/10 * * ? * * *"等
*/
void schedule(String name, String group, String cronExpression);
/**
* 根据 Quartz Cron Expression 调试任务
*
* @param cronExpression
* Quartz CronExpression
*/
void schedule(CronExpression cronExpression);
/**
* 根据 Quartz Cron Expression 调试任务
*
* @param name
* Quartz CronTrigger名称
* @param cronExpression
* Quartz CronExpression
*/
void schedule(String name, CronExpression cronExpression);
/**
* 根据 Quartz Cron Expression 调试任务
*
* @param name
* Quartz CronTrigger名称
* @param group
* Quartz CronTrigger组
* @param cronExpression
* Quartz CronExpression
*/
void schedule(String name, String group, CronExpression cronExpression);
/**
* 在startTime时执行调试一次
*
* @param startTime
* 调度开始时间
*/
void schedule(Date startTime);
void schedule(Date startTime, String group);
/**
* 在startTime时执行调试一次
*
* @param name
* Quartz SimpleTrigger 名称
* @param startTime
* 调度开始时间
*/
void schedule(String name, Date startTime);
void schedule(String name, Date startTime, String group);
/**
* 在startTime时执行调试,endTime结束执行调度
*
* @param startTime
* 调度开始时间
* @p