quartz的動態定時任務

之前在項目中的時候都是用的靜態定時任務,即在配置文件中寫好了何時由誰來作什麼事。後來無聊的時候就以爲這樣不能知足全部的需求,就像QQ的提醒,應該也是個動態的,由用戶去建立了一個定時通知任務,而後QQ服務器在指定的時間就會通知QQ用戶。固然QQ裏面的使用的不僅是動態的定時任務了。java


廢話很少說,仍是直接上代碼。spring

首先是spring的配置數據庫

<!-- quartz-2.x的配置 start  -->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<!-- quartz-2.x的配置 end  -->

聲明一個quartz的工廠就行,其它的由程序來動態完成。xcode

定時任務實體類(可存放到數據庫中),服務器

import com.xyan.frame.base.model.BaseModel;

public class ScheduleJobModel extends BaseModel{
    
    /** 任務名稱 */
    private String jobName;
    /** 任務分組 */
    private String jobGroup;
    /** 任務狀態 0禁用 1啓用 2刪除*/
    private String jobStatus;
    /** 任務運行時間表達式 */
    private String cronExpression;
    /** 任務描述 */
    private String remark;
    
    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 getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

注:BaseModel是我自定義的類,用於統一主鍵的。
app

而後就是任務執行監控了,任務運行入口,即Job實現類,在這裏我把它看做工廠類:ide

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.xyan.frame.quartz.model.ScheduleJobModel;

public class QuartzJobFactory implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println();
        System.out.println("任務成功運行");
        ScheduleJobModel scheduleJob = (ScheduleJobModel)context.getMergedJobDataMap().get("scheduleJob");
        System.out.println("任務名稱 = [" + scheduleJob.getJobName() + "]");
        /*
        此處能夠添加本身真正的業務邏輯
        */
        System.out.println();
    }
}

以後就是調用工具了,工具類代碼以下:工具

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
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.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.xyan.frame.quartz.model.ScheduleJobModel;
import com.xyan.frame.util.SpringUtil;

/**
 * @author wangming
 */
public class JobUtils {

	private static org.springframework.scheduling.quartz.SchedulerFactoryBean schedulerFactoryBean= SpringUtil.getBean(SchedulerFactoryBean.class);

	/**
	 * 添加任務並當即執行
	 * @param jobList
	 * @throws SchedulerException
	 */
	public static void addJob(List<ScheduleJobModel> jobList) throws SchedulerException {
		// schedulerFactoryBean 由spring建立注入
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		for (ScheduleJobModel job : jobList) {
			TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
			// 獲取trigger,即在spring配置文件中定義的 bean id="myTrigger"
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			// 不存在,建立一個
			if (null == trigger) {
				JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(job.getJobName(),job.getJobGroup()).build();
				jobDetail.getJobDataMap().put("scheduleJob", job);
				// 表達式調度構建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
				// 按新的cronExpression表達式構建一個新的trigger
				trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
				scheduler.scheduleJob(jobDetail, trigger);
			} else {
				// Trigger已存在,那麼更新相應的定時設置
				// 表達式調度構建器
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder .cronSchedule(job.getCronExpression());
				// 按新的cronExpression表達式從新構建trigger
				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey) .withSchedule(scheduleBuilder).build();
				// 按新的trigger從新設置job執行
				scheduler.rescheduleJob(triggerKey, trigger);
			}
		}
	}

	
	
	
	/**
	 *@Auhor:wangming
	 *@Description:獲取計劃中的任務
	 *@return
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:11:56
	 */
	public static List<ScheduleJobModel> getPlanTask() throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		List<ScheduleJobModel> jobList = new ArrayList<ScheduleJobModel>();
		for (JobKey jobKey : jobKeys) {
			List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			for (Trigger trigger : triggers) {
				ScheduleJobModel job = new ScheduleJobModel();
				job.setJobName(jobKey.getName());
				job.setJobGroup(jobKey.getGroup());
				job.setRemark("觸發器:" + trigger.getKey());
				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);
				}
				jobList.add(job);
			}
		}
		return jobList;
	}

	
	/**
	 *@Auhor:wangming
	 *@Description:獲取運行中的任務
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:13:10
	 */
	public static void getRunningTask() throws SchedulerException {

		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		List<JobExecutionContext> executingJobs = scheduler
				.getCurrentlyExecutingJobs();
		List<ScheduleJobModel> jobList = new ArrayList<ScheduleJobModel>(
				executingJobs.size());
		for (JobExecutionContext executingJob : executingJobs) {
			ScheduleJobModel job = new ScheduleJobModel();
			JobDetail jobDetail = executingJob.getJobDetail();
			JobKey jobKey = jobDetail.getKey();
			Trigger trigger = executingJob.getTrigger();
			job.setJobName(jobKey.getName());
			job.setJobGroup(jobKey.getGroup());
			job.setRemark("觸發器:" + trigger.getKey());
			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);
			}
			jobList.add(job);
		}
	}

	
	/**
	 *@Auhor:wangming
	 *@Description:暫停一個任務
	 *@param scheduleJob
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:13:48
	 */
	public static void pauseJob(ScheduleJobModel scheduleJob)
			throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),
				scheduleJob.getJobGroup());
		scheduler.pauseJob(jobKey);

	}

	/**
	 *@Auhor:wangming
	 *@Description:恢復一個任務
	 *@param scheduleJob
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:14:02
	 */
	public static void resume(ScheduleJobModel scheduleJob)
			throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),
				scheduleJob.getJobGroup());
		scheduler.resumeJob(jobKey);
	}


	/**
	 *@Auhor:wangming
	 *@Description:刪除一個任務
	 *@param scheduleJob
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:14:21
	 */
	public static void delete(ScheduleJobModel scheduleJob)
			throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),
				scheduleJob.getJobGroup());
		scheduler.deleteJob(jobKey);
	}


	/**
	 *@Auhor:wangming
	 *@Description:(用一句話描述)
	 *@param scheduleJob
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:14:38
	 */
	public static void noWaitRun(ScheduleJobModel scheduleJob)
			throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(),
				scheduleJob.getJobGroup());
		scheduler.triggerJob(jobKey);
	}

	/**
	 *@Auhor:wangming
	 *@Description:更新一個任務
	 *@param scheduleJob
	 *@throws SchedulerException
	 *@Date:2016年3月30日 下午3:15:37
	 */
	public static void update(ScheduleJobModel scheduleJob)
			throws SchedulerException {
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(),
				scheduleJob.getJobGroup());
		// 獲取trigger,即在spring配置文件中定義的 bean id="myTrigger"
		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);
	}
}

完成以上的步驟之後就能夠在項目中動態的調用了,如個人測試代碼:測試

@Autowired
    private ScheduleJobService jobServicee;
    
    @RequestMapping(value = "testJob")
    @ResponseBody
    public String testJob() throws SchedulerException {
        List<ScheduleJobModel> jobList=jobServicee.selectByExample(null);
        JobUtils.addJob(jobList);
        return "test";
    }
    
    @RequestMapping(value = "pauseJob")
    @ResponseBody
    public String pauseJob() throws SchedulerException {
        ScheduleJobModel job=jobServicee.selectByPrimaryKey(3L);
        JobUtils.pause(job);
        return "test";
    }


到這裏,quartz 2的動態定時任務功能算是告一段落了,對經常使用的一些功能進行了實現,相信能夠知足通常項目的需求了。固然了,有不少地方仍是能夠再優化的。
優化


參考:http://www.dexcoder.com/selfly/series/20

相關文章
相關標籤/搜索