`
53873039oycg
  • 浏览: 837262 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

动态配置Quartz定时任务的思路

阅读更多

     本文前置条件:Quartz 2.2.1, Spring 3.1以上版本,Quartz 2以下类似,只是具体类中对于配置动态任务写法不同。本文所说的动态是指把定时任务动态配置在数据库中。
     本文只是简单的写下思路,写的不好请见谅!

    主要思路如下:

      1)首先配置一个定时任务的类,TaskInfo,可以如下

     

/**
 * 定时任务信息
 * 
 */
public class TaskInfo {

	/** 任务id */
	private long jobId;

	/** 定时任务全路径 ,定时任务必须实现AbsTask eg com.task */
	private String jobClass;

	/** 任务名称 */
	private String jobName;

	/** 任务分组 */
	private String jobGroup;

	/** 任务状态 0禁用 1启用 2删除 */
	private String jobStatus;

	/** 任务运行时间表达式 */
	private String cronExpression;

	/** 任务描述 */
	private String desc;

	public long getJobId() {
		return jobId;
	}

	public void setJobId(long jobId) {
		this.jobId = jobId;
	}

	public String getJobClass() {
		return jobClass;
	}

	public void setJobClass(String jobClass) {
		this.jobClass = jobClass;
	}

	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;
	}

}

    2)要想动态配置,必须先配置一个后台定时任务在一定间隔内扫描表中的数据,且该后台定时任务不能重复配置,彻底点就是禁止改后台定时任务出现在表中

    3)为和后台定时任务区分,可以定义一个抽象类,具体类必须实现该类的方法。抽象类中的方法可以类似于 execute(long taskId),这样好处是可以在数据库中配置一张定时任务运行参数表,不配置参数表也行。

    4)具体功能的类实现抽象类

    5)由于在类中配置定时任务时候,创建JobDetail时候具体任务类必须实现Job接口,如下所示

   

JobDetail jobDetail = JobBuilder.newJob(TaskRegJob.class)
						.withIdentity(task.getJobName(), task.getJobGroup())
						.build();

    所以要一个实现了Job接口的定时任务作为中介,该定时任务以配置的Cron表达式运行,在

  

public void execute(JobExecutionContext context)
			throws JobExecutionException {

    方法内调用配置类的方法。

   6)用于数据库中的数据在后台定时任务运行间隔内可能被删除,可以能被新增或者修改,这里只有删除特殊点,新增只是在配置个TaskRegJob而已,修改则只需要改下定时任务的Cron表达式而已,删除的定时任务可能正在运行,这时候就要想个办法处理,本人认为可以这样处理:

   在TaskScanJob后台定时任务方法内先删除没有正在运行的定时任务,如何得到正在运行的定时任务可以这样做:

  

Scheduler scheduler = context.getScheduler();
		List runningJobs = null;
		try {
			runningJobs = scheduler.getCurrentlyExecutingJobs();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}

    判断是否正在运行:

  

private static boolean isRunning(JobKey jobKey, List runningJobs)
			throws Exception {
		boolean rtn = false;
		for (Iterator iter = runningJobs.iterator(); iter.hasNext();) {
			JobExecutionContext item = (JobExecutionContext) iter.next();
			if ((item.getJobDetail().getKey().equals(jobKey))) {
				rtn = true;
				break;
			}
		}
		return rtn;
	}

    得到当前配置的所有定时任务:

  

GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
			try {
				Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
				for (JobKey jobKey : jobKeys) {

}

    删除定时任务:

   

boolean rtn = scheduler.deleteJob(jobKey);

    删除的定时任务在下次启动时生效

    在TaskRegJob定时任务中,使用taskId去数据库取定时任务信息,如果取不到说明该定时任务已经被删除,只是用于正在运行所以不满足运行完成条件没有被删除,这时候可以这样做:

  

try {
			taskId = data.getLong("TASK_ID");
			task = DB.getTaskById(taskId);
		} catch (Throwable ex) {
			log.error("任务执行异常,任务ID:" + taskId
					+ ",有可能的原因是,此任务已经加入调度,执行时此任务已经被删除", ex);
			try {
				log.info("准备删除当前任务:" + context.getJobDetail().getKey());
				context.getScheduler().deleteJob(
						context.getJobDetail().getKey());
			} catch (SchedulerException e) {
				throw new JobExecutionException("任务删除异常,任务ID:" + taskId
						+ ",有可能的原因是:", ex);
			}
			throw new JobExecutionException("任务执行异常,任务ID:" + taskId
					+ ",有可能的原因是,此任务已经加入调度,执行时此任务已经被删除", ex);
		}

    说明,得到当前定时任务配置的数据方法如下:

 

JobDataMap data = context.getJobDetail().getJobDataMap();

    这样做了之后,该定时任务就在下次启动时删除不会启动。

    得到当前正在运行的普通定时任务(非后台)方法如下:

  

for (iter = runningJobs.iterator(); iter.hasNext();) {
			JobExecutionContext item = (JobExecutionContext) iter.next();
			if ((item.getJobInstance() instanceof TaskRegJob)) {
				log.info("系统中有正在运行的任务,任务ID:"
						+ item.getJobDetail().getJobDataMap()
								.getLongValue("TASK_ID") + ",执行类:"
						+ item.getJobDetail().getJobClass().getName());
			}
}

   总结:

        本文所说的方法:主要是先配置一个后台定时任务扫描数据库,采用另一个定时任务以配置的时间间隔调用具体的方法达到动态配置定时任务的效果。

   主要缺点如下:

       1必须先配置一个后台定时任务。

       2具体类实现抽象类,一个具体类一次只能配置一个定时任务,可以多次配置。也就是说定时任务的方法是固定的。

       全文完,写的不好的地方请指教,有更好的方法请留言。 

分享到:
评论
1 楼 conishyy 2014-05-22  
很不错的文章。正是我需要的,不知道你实现了没?可不可以共享一份给我!谢谢!yangyao86@126.com

相关推荐

    定时任务项目的设计思路

    标题“定时任务项目的设计思路”涉及的是在软件开发中如何规划和实现自动执行的作业,通常称为cron job或定时任务。这些任务可以在特定时间点或按照预设的时间间隔自动触发,用于数据同步、报告生成、清理旧记录等...

    Java任务调度框架Quartz教程实例

    ### Java任务调度框架...综上所述,Quartz是一个强大且灵活的任务调度框架,它不仅可以满足基础的定时任务需求,还能处理复杂多变的任务调度场景。无论是个人开发者还是企业级项目,都可以从Quartz的强大功能中获益。

    quartz封装

    - Quartz是一个完全由Java编写的、基于JDBC的作业调度库,它能够在Java应用中实现精确的定时任务调度。 - 它支持 cron 表达式、简单计划器以及自定义调度策略,满足各种复杂的需求。 - Quartz提供了一个API,用于...

    spring+quartz需要的4个jar包 不需要6个

    通过这样的配置,你可以在不增加额外负担的情况下,有效地利用Spring和Quartz进行任务调度。只需关注业务逻辑,而不必关心任务的执行细节。这就是使用这4个核心jar包实现Spring和Quartz集成的基本思路。

    web定时器的实现思路

    这篇博文链接指向的是一个关于在Java应用程序中实现Web定时任务的讨论,虽然具体的细节没有给出,但我们可以根据这个主题来深入探讨Web定时器的实现思路。 1. **Java定时框架** - ** Quartz Scheduler**:Quartz是...

    Quartz开源作业调度库 v2.3.2.zip

    通过理解其核心概念和API,开发者可以构建出高效、灵活的定时任务系统,从而提高应用程序的自动化程度和效率。在学习和使用Quartz的过程中,可以深入探究其源码,这不仅有助于理解其工作原理,还能提升自身的编程...

    TBSchedule资料

    1. 定时任务:TBSchedule可以方便地设置定时任务,如每天凌晨备份数据库、定时发送邮件等,只需定义任务执行的cron表达式即可。 2. 依赖任务:对于存在先后执行顺序的任务,TBSchedule支持任务间的依赖关系,确保...

    xxl-job-master

    它的设计思路和实现方式为企业级应用提供了高效、稳定、灵活的定时任务解决方案。无论是小型项目还是大型企业,都可以根据实际需求选择使用XXL-JOB来管理定时任务,从而提高系统的自动化程度和运维效率。

    CommonJob.zip

    首先,通用定时任务是指能够应用于各种场景,具有高度可复用性和可配置性的定时任务。这些任务通常由调度器如Spring Scheduler或Quartz等库来管理,它们允许设置执行频率、启动时间等参数。在Java世界中,Spring框架...

    Maven spring+springMvc+MyBatics+Redis+Shiro+PageHelp+Quartz+Log4j

    7. Quartz:Quartz是Java的作业调度库,可以安排任务在特定时间执行,如定时任务、计划任务等。在项目中,Quartz可能被用来执行周期性的后台任务。 8. Log4j:Log4j是一个日志记录框架,提供灵活的日志配置,帮助...

    基于ssh的任务调度系统毕业设计(项目报告+答辩PPT+源代码+数据库+截图+部署视频).zip

    任务调度通常涉及到定时任务、周期性任务和一次性任务。例如,可能需要按照预定的时间点执行数据备份、清理过期记录等操作。这通常会用到Quartz或Spring的TaskExecution和TaskScheduler接口来实现。Quartz是一个开源...

    基于Java调度系统的源代码.zip

    Spring Task是Spring框架的一部分,提供了在应用内创建和执行定时任务的能力。如果源码中使用了这些库,我们需要理解其配置、调度策略以及如何定义和管理任务。 2. **任务(Task)定义** 调度系统中的任务通常由...

    基于ssh的任务调度系统(项目报告+答辩PPT+源代码+数据库+截图+辅导视频).zip

    可能采用了Quartz或Spring的TaskScheduler等开源调度库,允许定义任务执行的周期、优先级,并在指定时间自动触发任务执行。任务可以是数据处理、定时通知或其他任何需要定时运行的操作。 3. 项目报告文档资料: 这...

    java毕设之基于SSH的任务调度系统的设计与实现

    【一定要读我】(关于任务调度).txt很可能是项目作者对任务调度系统特别注意事项或使用教程的说明,包含了如何配置和启动调度服务、如何添加和管理任务等关键操作步骤。 总的来说,这个基于SSH的任务调度系统项目为...

    基于ssh的任务调度系统设计与实现(项目报告+答辩PPT+源代码+数据库+截图+辅导视频).zip

    2. **任务调度**:任务调度系统的核心功能是计划、管理和执行定时任务。它通常包括任务定义、调度策略设定、执行监控以及异常处理等模块。在这个项目中,可能采用了Quartz或Spring Task等开源任务调度库,它们允许...

    JSP动态生成HTML静态页面源码

    具体实现可能涉及到Java Servlet、JSP标签库(Tag Library)、文件I/O操作以及可能的定时任务(如Quartz或Spring Scheduler)来定期检查和更新静态页面。 学习这个源码,你可以深入理解JSP与静态页面之间的转换机制...

    java源码:Java批量作业执行框架 MyBatchFramework.zip

    6. **作业调度**:MyBatchFramework 可能集成了定时任务调度器,如Quartz或Spring Scheduler,使得作业可以按照预定的时间间隔自动启动。 7. **插件扩展**:为了满足不同需求,框架可能会支持自定义任务处理器、...

    -基于springboot OA自动化办公系统源码【www.java1234.com]].zip

    3. Task调度:使用Springboot的Task或者Quartz定时任务框架,实现周期性任务,如定时备份、定时提醒等。 4. 数据缓存:集成Redis或Ehcache,提升系统性能,减少数据库压力。 五、开发与调试 1. IDE集成:使用IDEA或...

    若依RuoYi框架剖析笔记,该笔记是在学习江南一点雨所录课程再结合自己的理解所写

    30、**定时任务**:使用Quartz等工具设置定时任务,自动化执行周期性任务。 31、**流程表单**:设计和实现与流程相关的业务表单,如审批表单。 32、**绘制流程图**:使用Flowable提供的工具或第三方软件绘制流程图...

    spring-boot-starter-validation-1.3.5.RELEASE.zip

    描述中的"odelay.zip, 提供延迟执行操作的灵长类动物延迟反应"可能是指一个名为odelay的开源项目,它可能实现了类似于定时任务或者延时队列的功能。"灵长类动物延迟反应"可能是对项目特性的比喻,暗示该项目能够实现...

Global site tag (gtag.js) - Google Analytics