文档章节

quartz的动态定时任务

淡看江湖
 淡看江湖
发布于 2016/03/29 17:37
字数 1329
阅读 171
收藏 16

以前在项目中的时候都是用的静态定时任务,即在配置文件中写好了什么时候由谁来做什么事。后来无聊的时候就觉得这样不能满足所有的需求,就像QQ的提醒,应该也是个动态的,由用户去创建了一个定时通知任务,然后QQ服务器在指定的时间就会通知QQ用户。当然QQ里面的使用的不只是动态的定时任务了。


废话不多说,还是直接上代码。

首先是spring的配置

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

声明一个quartz的工厂就行,其它的由程序来动态完成。

定时任务实体类(可存放到数据库中),

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是我自定义的类,用于统一主键的。

然后就是任务执行监控了,任务运行入口,即Job实现类,在这里我把它看作工厂类:

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


© 著作权归作者所有

淡看江湖
粉丝 36
博文 86
码字总数 92924
作品 0
浦东
后端工程师
私信 提问
quartz分布式集群部署并且可视化配置job定时任务

项目使用quartz框架完成了定时任务集群部署调度,并且对quartz进一步封装完成在web界面可动态配置定时任务。定时任务如果集群部署,到达时间点时,同一个任务只能在其中一台机器上执行。对于...

hxt168
2016/07/04
1K
1
Spring Quartz 任务静态配置和动态添加

Quartz任务可以静态配置到配置文件中,也可以动态添加. 1.Quartz任务 静态配置 其中 <property name="concurrent" value="false"/>,是设置job不能并发执行。 2.Quartz任务 动态添加 定时器动......

满小茂
2016/12/20
455
0
jfinal定时调度任务插件QuartzPlugin

pom.xml依赖quartz quartz_config.properties(quartz配置) quartz_job.properties(任务配置,默认的调度任务可以在这里添加) FormaterCronExpression.java(日期转cron定时表达式类) JobBean...

peter_qyq
2017/07/18
0
0
Quartz的搭建、应用(单独使用Quartz)

Quartz在Java构建的系统中,是十分常用的定时任务框架。 本文,记录、介绍Quartz的简单入门的单独搭建(此文入门学习Quartz为主,并非基于Spring托管形式)。 > 参考的优秀资料 Quartz Quick...

Zero零_度
2016/07/27
118
0
Quartz 2.x与Spring 动态整合

一、Quartz简介 Quartz是一个由James House创立的开源项目,是一个功能强大的作业调度工具,可以计划的执行任务,定时、循环或在某一个时间来执行我们需要做的事,这可以给我们工作上带来很大...

qllinhongyu
2014/07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ES6

ES6:不改变原理的基础上,让API变得更简单 一、let:代替var用于声明变量 1、var的缺点: (1)声明提前 (2)没有块级作用域 2、let的优点: (1)组织了申明提前 (2)让let所在的块({}),...

wytao1995
今天
3
0
kubernetes 环境搭建 —— minikube

创建集群 minikube start 搭建好 k8s 集群后,可以查看集群的状态以及部署应用。主要用到的是 k8s 的 api,这通常需借助于 kutectl 命令行工具 基本操作 kubectl versionkubectl cluster-i...

lemos
今天
9
0
关于js混淆与反混淆还原操作

使用js的混淆加密,其目的是为了保护我们的前端代码逻辑,对应一些搞技术吃饭的公司来说,为了防止被竞争对手抓取或使用自己的代码,就会考虑如何加密,或者混淆js来达到代码保护。 1、为什么...

开源oschina
今天
11
0
用盛金公式解三次方程(ansi c版)

/* cc cubic.c -lm gcc cubic.c -lm Shengjin's Formulas Univariate cubic equation aX ^ 3 + bX ^ 2 + cX + d = 0, (a, b, c, d < R, and a!= 0). Multiple root disc......

wangxuwei
今天
9
0
JBolt开发平台入门(16)- 弹出Dialog显示指定区域的html内容

在JBolt里,有个主从表Demo。 子表中除了普通的table显示,还有其它从表显示形式 比如下方案例:是针对一个升级管理子表中存放版本的changelog富文本信息。 需求是点击左上角的弹出查看按钮,...

山东-小木
今天
45
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部