需求:
需要每天定时去获取四大渠道商:谷歌,百度,搜搜,搜狗的关键词,广告组,广告系列,广告商账号等汇总数据,客户可以从页面直观看到各个任务执行结果,可以手动直接去编辑更新任务的执行频率,执行参数以及启停任务;也可以新增删除任务。
设计中项目分为前后台两个项目:
后台负责定时任务的自动执行,以及提供定时任务的修改,新增,删除等服务接口,以供前台调用;前台负责展示所有任务执行状态,参数(执行频率,任务对于的渠道商id,账号id)以及任务名称(谷歌服装广告商系列报表下载),提供任务编辑功能,可以新增,删除,修改任务信息。
数据库设计:
CRON_TASK任务信息维护表:
id(自增长主键),target_object(执行对象,这里对应的是spring里配置得bean.id),cron_expression_r(执行频率,对应的quartz的执行频率),还有与业务有关的参数信息列:channel_id(渠道商id),account_id(账号id)等,创建人,创建日期...
CRON_TASK_STATUS任务状态信息表:
id(自增长主键),task_id(对应CRON_TASK.id),run_status(执行状态位,执行成功,执行失败,未执行,正在执行等),run_start_time(执行开始时间),run_end_time(执行结束时间),等..
后台代码设计:
通过数据库设计,后台已经可以直接通过数据库获取到所有任务信息了,但是如何把任务信息和我们后台的定时任务挂钩呢?
1:通过监听器或者servlet,spring等机制在web服务器自启动的时候加载所有任务信息
2:因为任务是需要支持动态新增,修改,所以这里不建议通过spring xml方式来方式来配置管理quartz任务,直接通过java代码调用得方式来管理任务;
调用quarts的基本常用步骤,以及几个常用对象:
Scheduler sched =StdSchedulerFactory.getDefaultScheduler();
JobDetail job = newJobDetail();
//这里很重要,我们通过jobDetail对象得setName来存储每一个任务得主键id
job.setName(e.getCronId().toString ());
//一般逻辑来说,我们需要为每一个任务建立不同得jobClass,但是我们这里只针对了一个,上面得setName就启动作用了,我们可以再CronStart里获取得任务id,那也就获取到它得bean.id了,我们就可以通过BeanFactory获取其它方式获取bean实例,这样cronStart就逻辑上变成动态的任务实例了。
job.setJobClass(CronStart.class);
CronTrigger trigger = newCronTrigger();
String ce =e.getCronexpression_r();
//任务执行频率
trigger.setCronexpression_r(ce);
//触发器对应的任务id主键
trigger.setName(e.getCronId().toString());
sched.scheduleJob(job,trigger);
sched.addJob(job,true);
3:设计cronStart
publicclass CronStart implements Job {
@Override
public voidexecute(JobExecutionContext executionContext)
throwsJobExecutionException{
//获取到任务id
executionContext.getJobDetail().getName();
//获取数据信息。。。
//调用targetObject。。
但是这里是需要执行targetObject的方法得,有两种办法
一种办法是数据库也同时存储对应得method方法名称,然后我们获取到bean实例后,通过反射到触发方法的执行
还有一种方法是我们可以让所有得任务bean去继承通过父类BasicTask,该父类提供了一个抽象方法
public abstract voiddoTask(CronTaskParameter ctp) throws Exception;
也就是我们默认所有任务的执行方法就是doTask这个方法,而方法中的参数也就是数据库存储任务信息的java对象,那就可以这样来获取任务并执行了
BasicTask task =BeanFactory.getBean("targetObject");
task.doTask(ctp);
}
}
4:为前台提供任务编辑的接口方法:
更新任务
publicint updateCronTask(CronTaskFlow cronTaskFlow){
//截取相关代码
//更新任务链先删除任务链sched.deleteJob(cronTaskFlow.getTaskFlowId().toString(),sched.DEFAULT_GROUP);
//再新增任务链
if (pause.intValue() ==1) {
JobDetail job = newJobDetail();job.setJobClass(CronFlowStart.class);
job.setName(cronTaskFlow.getTaskFlowId().toString());
cronTrigger = newCronTrigger();
String ce =cronTaskFlow.getTaskFlowexpression_r();
cronTrigger.setCronexpression_r(ce);
cronTrigger.setName(cronTaskFlow.getTaskFlowId().toString())
sched.scheduleJob(job,cronTrigger);
sched.addJob(job,true);
}
}