在本文中,通过一个监听器创建任务的例子说明如何不通过quartz.xml配置初始化任务(当然,可以在任何时候创建任务)。也说明在任务管理器中如何管理任务(创建、修改、暂停、运行一次)等。
1、监听器创建任务
(1) 在web.xml中配置监听器
<listener>
<display-name>Spring</display-name>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
<listener-class>com.test.task.quartz.ScheduledTaskListener</listener-class>
</listener>
(2)ScheduledTaskListener.java
package com.test.task.quartz;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.test.framework.utils.SpringContextUtil;
import com.test.task.service.ScheduledTaskService;
import com.test.train.service.TrainingScheduleService;
import com.test.userinfotask.service.UserInfoTaskService;
/**
* 计划任务监听器,在系统启动时,检查系统中是否有需要重新启动的计划任务
* 若有,则恢复
* @2014-7-25
* @author Schema
*/
public class ScheduledTaskListener implements ServletContextListener {
private Log logger = LogFactory.getLog(this.getClass());
public void contextDestroyed(ServletContextEvent context) {
System.out.println(this.getClass().getName()+":contextDestroyed...........................");
}
public void contextInitialized(ServletContextEvent context) {
logger.info(this.getClass().getName()+":开始恢复计划任务...........");
//待办定时任务恢复
ScheduledTaskService scheduledTaskService=(ScheduledTaskService)SpringContextUtil.getBean("scheduledTaskService");
scheduledTaskService.recoveryTask();
logger.info(this.getClass().getName()+":恢复计划任务结束...........");
}
}
(3)ScheduledTaskServiceImpl.java实现类中的recoveryTask()方法。
public void recoveryTask() {
//获取业务待办
List<ScheduledTask> list = this.getScheduledTaskList();
if (list != null && list.size() > 0) {
for (ScheduledTask st:list) {
if (st.getTaskType() == 0 && st.getSendDate().before(new Date(System.currentTimeMillis()))) continue;
if (st.getValve() == 1) {
//创建job
this.createJob(st);
}
}
}
}
<pre name="code" class="html">public void createJob(ScheduledTask st) {
if (st == null || this.isEmpty(st.getId())) return;
if (st.getValve() == 0 || this.jobIsExists(st.getId())) return;
try {
//创建一个JobDetail实例,指定组及名称,指定ScheduledTaskJob,具体执行类
JobDetailImpl jobDetail = new JobDetailImpl(ScheduledTaskJob.NAME_JOB+st.getId(),
ScheduledTaskJob.GROUP_JOB, ScheduledTaskJob.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("scheduledTask", st);
map.put("recipientsList", this.getRecipientsList(st.getId()));
jobDetail.setJobDataMap(new JobDataMap(map));
//根据任务类型来判断发送周期
String triName = ScheduledTaskJob.NAME_TRIGGER+st.getId();
//调度器
Scheduler scheduler = schedulerFactoryBean.getScheduler();
if (st.getTaskType() == 0) {
if (st.getSendDate().before(new Date())) return;
SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl(triName, ScheduledTaskJob.GROUP_TRIGGER);
simpleTrigger.setStartTime(st.getSendDate());
scheduler.scheduleJob(jobDetail, simpleTrigger);
simpleTrigger.setRepeatCount(1); //重复一次
scheduler.start();
} else {
String dateExp = st.getDateExpression();
//创建CronTrigger实例,指定组及名称
CronTriggerImpl cronTrigger = new CronTriggerImpl(triName, ScheduledTaskJob.GROUP_TRIGGER);
if(st.getSendDate().after(new Date(System.currentTimeMillis()))){
cronTrigger.setStartTime(st.getSendDate());
}
CronExpression cexp = new CronExpression(this.getCronExpression(st));
cronTrigger.setCronExpression(cexp);
scheduler.scheduleJob(jobDetail, cronTrigger); // 注册并进行调度
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
这样任务就创建起来了,并序列化到数据库中。需要注意的是,为了防止多个应用程序在启动时重复创建任务,每次创建之前都需要判定当前任务是否存在scheduler.checkExist(new Trigger(triggerName,triggerGroup))。
二、通过任务管理获取当前任务列表,调度任务、修改任务等(核心类SchedulerServiceImpl.java)。
package com.test.framework.quartz.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import com.test.framework.quartz.job.QuartzJobFactory;
import com.test.framework.quartz.service.SchedulerService;
import com.test.framework.quartz.vo.ScheduleJob;
import com.test.framework.query.model.QueryCondition;
import com.test.framework.utils.PageInfo;
import com.test.framework.utils.StrUtil;
@Service("schedulerService")
public class SchedulerServiceImpl implements SchedulerService {
@Autowired(required = false)
private SchedulerFactoryBean schedulerFactoryBean;//注入bean
/**
* 调度或更新单个任务 仅限于CronTrigger的任务
*/
public void scheduleCronSingleJob(ScheduleJob job) throws SchedulerException, ClassNotFoundException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
List<ScheduleJob> jobList = getAllJobs();
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
// 获取trigger,即在spring配置文件中定义的
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(job.getJobClass()))
.withIdentity(job.getJobName(), job.getJobGroup()).withDescription(job.getDesc()).build();
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder)
.withDescription(job.getDesc()).build();
scheduler.scheduleJob(jobDetail, trigger);
} else {
// trigger已经存在,那么更细相应的定时设置
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger
.getTriggerBuilder()
.withIdentity(triggerKey)
.withSchedule(scheduleBuilder)
.withDescription(
job.getDesc().substring(
job.getDesc().indexOf("trigger:") > -1 ? job.getDesc().indexOf("trigger:") + 8 : 0))
.build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
}
/**
* 调度单个任务 SimpleTrigger 和 CronTrigger
*/
public void scheduleSingleJob(ScheduleJob job) throws SchedulerException, ClassNotFoundException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
List<ScheduleJob> jobList = getAllJobs();
TriggerKey triggerKey = TriggerKey.triggerKey(job.getTriggerName(), job.getTriggerGroup());
// 获取trigger
Trigger trigger = scheduler.getTrigger(triggerKey);
// 不存在,创建一个
// if (null == trigger) {
if (!scheduler.checkExists(triggerKey)) {
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(job.getJobClass()))
.withIdentity(job.getJobName(), job.getJobGroup()).withDescription(job.getDesc()).build();
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
trigger = setTriggerParam(job, triggerKey, triggerBuilder, trigger);
scheduler.scheduleJob(jobDetail, trigger);
} else {
// trigger已经存在,那么更细相应的定时设置
TriggerBuilder triggerBuilder = trigger.getTriggerBuilder();
trigger = setTriggerParam(job, triggerKey, triggerBuilder, trigger);
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
}
/**
* 设置trigger
*
* @param job
* @param triggerKey
* @param trigger
* @param triggerBuilder
*/
public Trigger setTriggerParam(ScheduleJob job, TriggerKey triggerKey, TriggerBuilder triggerBuilder,
Trigger trigger) {
if (job.getTriggerType().equals("CronTrigger")) {
CronScheduleBuilder cronBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
if (job.getStartTime() != null)
triggerBuilder.startAt(job.getStartTime());
if (job.getEndTime() != null)
triggerBuilder.endAt(job.getEndTime());
trigger = triggerBuilder.withIdentity(triggerKey).withSchedule(cronBuilder).withDescription(
job.getDesc().substring(
job.getDesc().indexOf("trigger:") > -1 ? job.getDesc().indexOf("trigger:") + 8 : 0))
.build();
} else if (job.getTriggerType().equals("SimpleTrigger")) {
SimpleScheduleBuilder simpleBuilder = SimpleScheduleBuilder.simpleSchedule();
if (job.getStartTime() != null)
triggerBuilder.startAt(job.getStartTime());
if (job.getEndTime() != null)
triggerBuilder.endAt(job.getEndTime());
if (StrUtil.isNotBlank(job.getRepeatType())) {
if (job.getRepeatType().equals("repeatForever"))
simpleBuilder = simpleBuilder.repeatForever();
else if (job.getRepeatType().equals("repeatHourlyForever")) {
if (job.getRepeatInterval() != null)
simpleBuilder = simpleBuilder.repeatHourlyForever(job.getRepeatInterval());
else
simpleBuilder = simpleBuilder.repeatHourlyForever();
} else if (job.getRepeatType().equals("repeatMinutelyForever")) {
if (job.getRepeatInterval() != null)
simpleBuilder = simpleBuilder.repeatMinutelyForever(job.getRepeatInterval());
else
simpleBuilder = simpleBuilder.repeatMinutelyForever();
} else if (job.getRepeatType().equals("repeatSecondlyForever")) {
if (job.getRepeatInterval() != null)
simpleBuilder = simpleBuilder.repeatSecondlyForever(job.getRepeatInterval());
else
simpleBuilder = simpleBuilder.repeatSecondlyForever();
} else if (job.getRepeatType().equals("repeatHourlyForTotalCount")) {
if (job.getRepeatCount() != null && job.getRepeatInterval() != null)
simpleBuilder = simpleBuilder.repeatHourlyForTotalCount(job.getRepeatCount(), job
.getRepeatInterval());
else if (job.getRepeatCount() != null)
simpleBuilder = simpleBuilder.repeatHourlyForTotalCount(job.getRepeatCount());
} else if (job.getRepeatType().equals("repeatMinutelyForTotalCount")) {
if (job.getRepeatCount() != null && job.getRepeatInterval() != null)
simpleBuilder = simpleBuilder.repeatMinutelyForTotalCount(job.getRepeatCount(), job
.getRepeatInterval());
else if (job.getRepeatCount() != null)
simpleBuilder = simpleBuilder.repeatMinutelyForTotalCount(job.getRepeatCount());
} else if (job.getRepeatType().equals("repeatSecondlyForTotalCount")) {
if (job.getRepeatCount() != null && job.getRepeatInterval() != null)
simpleBuilder = simpleBuilder.repeatSecondlyForTotalCount(job.getRepeatCount(), job
.getRepeatInterval());
else if (job.getRepeatCount() != null)
simpleBuilder = simpleBuilder.repeatSecondlyForTotalCount(job.getRepeatCount());
}
}
trigger = triggerBuilder.withIdentity(triggerKey).withSchedule(simpleBuilder).withDescription(
job.getDesc().substring(
job.getDesc().indexOf("trigger:") > -1 ? job.getDesc().indexOf("trigger:") + 8 : 0)
+ ";repeatType:" + job.getRepeatType()).build();
}
return trigger;
}
/**
* 获取所有计划中的任务
*/
public List<ScheduleJob> getAllJobs() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
ScheduleJob job = new ScheduleJob();
job.setJobId(jobKey.getGroup() + "_" + jobKey.getName());
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDesc("job:" + scheduler.getJobDetail(jobKey).getDescription() + ";trigger:"
+ trigger.getDescription());
job.setJobClass(scheduler.getJobDetail(jobKey).getJobClass().getName());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
job.setTriggerType("CronTrigger");
job.setStartTime(cronTrigger.getStartTime());
job.setEndTime(cronTrigger.getEndTime());
job.setTriggerName(cronTrigger.getKey().getName());
job.setTriggerGroup(cronTrigger.getKey().getGroup());
} else if (trigger instanceof SimpleTrigger) {
SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
job.setTriggerType("SimpleTrigger");
job.setStartTime(simpleTrigger.getStartTime());
job.setEndTime(simpleTrigger.getEndTime());
String repeatType = null;
if (simpleTrigger.getDescription().indexOf("repeatType:") > -1) {
repeatType = simpleTrigger.getDescription().substring(
simpleTrigger.getDescription().indexOf("repeatType:") + 11);
}
job.setRepeatType(repeatType);
job.setRepeatCount(simpleTrigger.getRepeatCount());
job.setRepeatInterval((int)simpleTrigger.getRepeatInterval());
if (repeatType != null && repeatType.indexOf("Secondly") > -1)
job.setRepeatIntervalStr(((int) simpleTrigger.getRepeatInterval() / 1000)+"秒");
else if (repeatType != null && repeatType.indexOf("Minutely") > -1)
job.setRepeatIntervalStr((int) simpleTrigger.getRepeatInterval() / 60000+"分钟");
else if (repeatType != null && repeatType.indexOf("Hourly") > -1)
job.setRepeatIntervalStr((int) simpleTrigger.getRepeatInterval() / 3600000+"小时");
job.setTriggerName(simpleTrigger.getKey().getName());
job.setTriggerGroup(simpleTrigger.getKey().getGroup());
}
jobList.add(job);
}
}
return jobList;
}
/**
* 获取单个任务
*/
public List<ScheduleJob> getScheduleJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = new JobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
for (Trigger trigger : triggers) {
ScheduleJob job = new ScheduleJob();
job.setJobId(jobKey.getGroup() + "_" + jobKey.getName());
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDesc("job:" + scheduler.getJobDetail(jobKey).getDescription() + " trigger:"
+ trigger.getDescription());
job.setJobClass(scheduler.getJobDetail(jobKey).getJobClass().getName());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
job.setTriggerType("CronTrigger");
job.setStartTime(cronTrigger.getStartTime());
job.setEndTime(cronTrigger.getEndTime());
job.setTriggerName(cronTrigger.getKey().getName());
job.setTriggerGroup(cronTrigger.getKey().getGroup());
} else if (trigger instanceof SimpleTrigger) {
SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
job.setTriggerType("SimpleTrigger");
job.setStartTime(simpleTrigger.getStartTime());
job.setEndTime(simpleTrigger.getEndTime());
String repeatType = null;
if (simpleTrigger.getDescription().indexOf("repeatType:") > -1) {
repeatType = simpleTrigger.getDescription().substring(
simpleTrigger.getDescription().indexOf("repeatType:") + 11);
}
job.setRepeatType(repeatType);
job.setRepeatCount(simpleTrigger.getRepeatCount());
if (repeatType != null && repeatType.indexOf("Secondly") > -1)
job.setRepeatInterval((int) simpleTrigger.getRepeatInterval() / 1000);
else if (repeatType != null && repeatType.indexOf("Minutely") > -1)
job.setRepeatInterval((int) simpleTrigger.getRepeatInterval() / 60000);
else if (repeatType != null && repeatType.indexOf("Hourly") > -1)
job.setRepeatInterval((int) simpleTrigger.getRepeatInterval() / 3600000);
job.setTriggerName(simpleTrigger.getKey().getName());
job.setTriggerGroup(simpleTrigger.getKey().getGroup());
}
jobList.add(job);
}
return jobList;
}
/**
* 暂停
*/
public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.pauseJob(jobKey);
}
/**
* 恢复运行
*/
public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.resumeJob(jobKey);
}
/**
* 删除
*/
public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);
}
/**
* 运行一次
*/
public void triggerJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.triggerJob(jobKey);
}
/**
* 更新时间表达式
*/
public void rescheduleJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
// 获取trigger
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按照新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
}
其中任务实体为
package com.test.framework.quartz.vo;
import java.util.Date;
/**
* 计划任务信息
*
* @author jrn1012 Date 15-4-23 Time 上午10:36
*
*/
public class ScheduleJob {
/** 任务id */
private String jobId;
/** 任务名称 */
private String jobName;
/** 任务分组 */
private String jobGroup;
/** trigger名称 */
private String triggerName;
/** trigger分组 */
private String triggerGroup;
/** 任务状态 0禁用 1启用 2删除 */
private String jobStatus;
/** 任务运行时间表达式
* CronTrigger
*/
private String cronExpression;
/** 任务描述 */
private String desc;
/** 反射方式注入class */
private String jobClass;
/**
* trigger类型 CronTrigger SimpleTrigger
*/
private String triggerType;
/**
* 开始时间 SimpleTrigger/CronTrigger
*/
private Date startTime;
/**
* 结束时间 SimpleTrigger/CronTrigger
*/
private Date endTime;
/**
* 重复次数 SimpleTrigger
*/
private Integer repeatCount;
/**
* 重复间隔 SimpleTrigger
*/
private Integer repeatInterval;
/**
* 重复间隔 SimpleTrigger 含单位
*/
private String repeatIntervalStr;
/**
* 重复类型
*/
private String repeatType;
public String getJobId() {
return jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getJobStatus() {
return jobStatus;
}
public void setJobStatus(String jobStatus) {
this.jobStatus = jobStatus;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getJobClass() {
return jobClass;
}
public void setJobClass(String jobClass) {
this.jobClass = jobClass;
}
public String getTriggerType() {
return triggerType;
}
public void setTriggerType(String triggerType) {
this.triggerType = triggerType;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Integer getRepeatCount() {
return repeatCount;
}
public void setRepeatCount(Integer repeatCount) {
this.repeatCount = repeatCount;
}
public Integer getRepeatInterval() {
return repeatInterval;
}
public void setRepeatInterval(Integer repeatInterval) {
this.repeatInterval = repeatInterval;
}
public String getRepeatType() {
return repeatType;
}
public void setRepeatType(String repeatType) {
this.repeatType = repeatType;
}
public String getRepeatIntervalStr() {
return repeatIntervalStr;
}
public void setRepeatIntervalStr(String repeatIntervalStr) {
this.repeatIntervalStr = repeatIntervalStr;
}
public String getTriggerName() {
return triggerName;
}
public void setTriggerName(String triggerName) {
this.triggerName = triggerName;
}
public String getTriggerGroup() {
return triggerGroup;
}
public void setTriggerGroup(String triggerGroup) {
this.triggerGroup = triggerGroup;
}
}
以上代码完成了quartz任务集中管理和集中监控,提高了可维护性,在发生问题时,便于发现。通过任务集群,提高了系统的可靠性。