本文基于spring3.2+quartz1.8.6配置,参考了网上的实现。
1、创建mysql数据库,执行quartz-1.8.6\docs\dbTables\tables_mysql.sql
2、新建quartz.properties来覆盖jar包中的此文件。
#==============================================================
#Configure Main Scheduler Properties
#==============================================================
org.quartz.scheduler.instanceName = quartzScheduler
org.quartz.scheduler.instanceId = AUTO
#==============================================================
#Configure JobStore
#==============================================================
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.jobStore.dataSource = myDS
#==============================================================
#Configure DataSource
#==============================================================
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://10.4.247.100:3306/quartz?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 30
#==============================================================
#Configure ThreadPool
#==============================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
3、MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法,是不支持序列化的,因此在把 QUARTZ 的 TASK 序列化进入数据库时就会抛错。需要自己实现MethodInvokingJobDetailFactoryBean 的功能,这里用MyDetailQuartzJobBean 替换。
public class MyDetailQuartzJobBean extends QuartzJobBean {
protected final Log log = LogFactory.getLog(getClass());
private String targetObject;
private String targetMethod;
private ApplicationContext ctx;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
//log.info("execute [" + targetObject + "] at once>>>>>>");
Object otargetObject = ctx.getBean(targetObject);
Method m = null;
try {
m = otargetObject.getClass().getMethod(targetMethod, new Class[] {JobExecutionContext.class});
m.invoke(otargetObject, new Object[] {context});
} catch (SecurityException e) {
log.error(e);
} catch (NoSuchMethodException e) {
log.error(e);
}
} catch (Exception e) {
throw new JobExecutionException(e);
}
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.ctx = applicationContext;
}
public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
}
4、编写业务调用类
public class FirstJob implements Job {
private final Log log = LogFactory.getLog(this.getClass());
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
log.info(this.getClass().getName() + "-->" + new Timestamp(System.currentTimeMillis()));
}
}
public class SecondJob implements Job {
private final Log log = LogFactory.getLog(this.getClass());
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
log.info(this.getClass().getName() + "-->" + new Timestamp(System.currentTimeMillis()));
}
}
5、spring配置文件
<!-- 1、配置文件中添加业务类,该类为调用的工作类 --> <bean id="firstJob" class="cn.sh.ideal.quartz.FirstJob" /> <bean id="secondJob" class="cn.sh.ideal.quartz.SecondJob" /> <!-- 2、定义任务,在spring文件中配置代理类 ,定义调用对象和调用对象的方法--> <bean id="firstTask" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>cn.sh.ideal.quartz.MyDetailQuartzJobBean</value> </property> <property name="jobDataAsMap"> <map> <entry key="targetObject" value="firstJob" /> <entry key="targetMethod" value="execute" /> </map> </property> </bean> <bean id="secondTask" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>cn.sh.ideal.quartz.MyDetailQuartzJobBean</value> </property> <property name="jobDataAsMap"> <map> <entry key="targetObject" value="secondJob" /> <entry key="targetMethod" value="execute" /> </map> </property> </bean> <!-- 3、配置触发器,定义触发时间,可以根据不同的时间对同一个任务定义多个触发器,下面是每隔10秒调用一个方法配置--> <!-- cron表达式 --> <bean id="firstCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="firstTask"/> <property name="cronExpression" value="10,20,30,40,50 * * * * ?"/> </bean> <bean id="secondCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="secondTask"/> <property name="cronExpression" value="5,15,25,35,45,55 * * * * ?"/> </bean> <!-- 4、配置调度器 ,容器启动就会执行调度程序 --> <!-- 总管理类,如果lazy-init='false',则容器启动时就会执行调度程序--> <!-- 如果lazy-init='true',则需要实例化该bean才能执行调度程序 --> <bean id="schdulerFactory" lazy-init="true" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="firstCronTrigger"/> <ref bean="secondCronTrigger"/> </list> </property> <property name="applicationContextSchedulerContextKey" value="applicationContext" /> <property name="configLocation" value="classpath:quartz.properties" /> </bean>
参考文档
1、Quartz集群配置 http://forhope.iteye.com/blog/1398990
2、quartz在集群环境下的最终解决方案 http://blog.youkuaiyun.com/lifetragedy/article/details/6212831
3、spring结合quartz的执行多任务的实现 http://rongdmmap-126-com.iteye.com/blog/1434378
4、cronmaker http://www.cronmaker.com/
5、Quartz学习研究 http://blog.youkuaiyun.com/jinnchang/article/details/8185786