`
wu_quanyin
  • 浏览: 208142 次
  • 性别: Icon_minigender_1
  • 来自: 福建省
社区版块
存档分类
最新评论

任务调度---Quartz

阅读更多

一,最近在开发任务调度(job)这一块,在此进行总结

1,在jdk中提供了基本的Timer,TimerTask可以用作其本的任务调度操作,不过功能不够强大

2,quartz框架为我们提供了一系列的任务调度操作,基本的应用操作等都很容易理解.(JobDetail,Trigger)


二,由于公司要使quartz与公司建模端平台互相协作,产生的问题


建模端(提供xml配置与job类)----------------------中间层(定时扫描xml,根据xml语义的改变而改变)


1,可配置,在起初时使用的是1.6版本,这个版本没有提供插件配置机制,在为如何定义xml,如何让线程合理操作烦恼,看了下官方文档,原来1.8中已经提供了可配置的插件机制,非常方便,

org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin(可认真查看此插件的源码)  这个类提供了全套的服务.,

.可在定义的xml中配置想要的job,此插件还提供了对此xml隔时对此进行查询操作,对xml中配置的内容意义识别(可删除,可替换)


2,在部暑到tomcat上出现了一个问题,那就是webappClassloader缓存了任务调度的xml,也就是说建模端对xml进行更改或是添加job,并不会被读取..

 .解决方案,跟踪了下源码发现插件中查找文件是使用了(classloader getResourceAsStream(String name))进行查找,

故自己重新写了个自定义的classloader,用来专门加载quartz

 

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 任务调度时查询classpath下的scheduler.xml时,
 * webappclassloader使用了缓存,不能及时更新
 * 该文件下的job,故重写classloader
 * 
 * @author wu_quanyin(09817) 
 * @version 1.0
 * @date 2010-08-19 下午01:53:25
 */
public class QuartzClassLoader extends URLClassLoader {

	public QuartzClassLoader(File directoryPath, ClassLoader parent) {

		super(new URL[0],parent);

		if(directoryPath.isDirectory()){
			File[] files=directoryPath.listFiles();
			for(int i=0;i<files.length;i++){
				try {
					this.addURL(files[i].toURI().toURL());
				} catch (MalformedURLException e) {
					e.printStackTrace();
				}
			}
		}

	}

	/**
	 * quartz查找scheduler.xml时,使用些方法查找
	 */
	public InputStream getResourceAsStream(String name) {
		URL url = getResource(name);
		try {
			return url != null ? url.openStream() : null;
		} catch (IOException e) {
			return null;
		}
	}
	
	 public URL getResource(String name) {
		 URL[] urls=this.getURLs();
		 for(int i=0;i<urls.length;i++){
			 if(urls[i].getPath().indexOf(name)!=-1){
				 return urls[i];
			 }
		 }
	 
	  return super.getResource(name);
	 }
	 

}

 

 

然后设置进(parent 为webappclassloader先查找quartzclassloader再查找parent)

 

/*
 * CopyRright (c) 2009-2015 www.fdauto.com
 */
package com.fdauto.bws.common.scheduler;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Properties;

import com.fdauto.bws.common.logger.SystemLogsHelper;
import com.fdauto.bws.service.config.BWSConfigHelper;

/**
 * 任务调度
 * 
 * @author wu_quanyin(09817)
 * @version 1.0
 * @date 2010-5-5 上午07:54:01
 */
public class QuartzStdScheduler {
	private Properties ps;
	private Object schedulerObject;
	private static QuartzStdScheduler inst;
	private static String jobs_full_path;
	private static String quartz_classpath;
	private static String scheduler_name;
	private QuartzClassLoader quartzClassLoader;

	static {
		jobs_full_path = BWSConfigHelper.getBWSConfig().getProperties()
				.getProperty("jobFiles");

		quartz_classpath = jobs_full_path.substring(0, jobs_full_path
				.lastIndexOf("/"));

		scheduler_name = jobs_full_path.substring(jobs_full_path
				.lastIndexOf("/") + 1);
	}

	private QuartzStdScheduler() {
		initial();
		schedulerObject = createScheduler();
	}

	/** 单例模式 */
	public static QuartzStdScheduler getInstance() {
		if (inst == null) {
			inst = new QuartzStdScheduler();
		}
		return inst;
	}

	/** 对属性进行初始化 */
	private void initial() {

		// -----------------------------------------以自定义的classLoader来控制quartz的执行
		quartzClassLoader = new QuartzClassLoader(new File(this.getClass()
				.getClassLoader().getResource(quartz_classpath).getFile()),
				this.getClass().getClassLoader());

		Thread.currentThread().setContextClassLoader(quartzClassLoader);

		// --------------------------------------------------------------初始化quartz的环境
		ps = new Properties();
		ps.setProperty(QuartzProperties.PROP_SCHED_INSTANCE_NAME,
				"DefaultQuartzScheduler");

		ps.setProperty(QuartzProperties.PROP_THREAD_COUNT, "10");

		ps.setProperty(QuartzProperties.PROP_THREAD_POOL_CLASS,
				"org.quartz.simpl.SimpleThreadPool");

		ps.setProperty(QuartzProperties.PROP_JOB_STORE_CLASS,
				"org.quartz.simpl.RAMJobStore");

		ps.setProperty("org.quartz.plugin.triggHistory.class",
				"org.quartz.plugins.history.LoggingJobHistoryPlugin");

		ps.setProperty(QuartzProperties.PROP_PLUGIN_CLASS,
				"org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin");

		ps.setProperty(QuartzProperties.PROP_PLUGIN_SCANINTERVAL, "180");

		/**
		 * 根据指定job文件进行创建,以逗号分隔文件,在bws.xml中配置路径
		 * com/fdauto/bws/common/scheduler/quartz_jobs.xml,
		 * com/fdauto/bws/common/scheduler/quartz_jobs2.xml
		 */
		ps.setProperty(QuartzProperties.PROP_PLUGIN_FILESNAME, scheduler_name);
	}

	/**
	 * 创建scheduler
	 * 
	 * @return
	 */
	private Object createScheduler() {
		try {
			Object schedulerFactoryObject = quartzClassLoader.loadClass(
					"org.quartz.impl.StdSchedulerFactory").getConstructor(
					new Class[] { Properties.class }).newInstance(
					new Object[] { ps });
			Method method = schedulerFactoryObject.getClass().getMethod(
					"getScheduler", new Class[] {});
			Object schedulerObject = method.invoke(schedulerFactoryObject,
					new Object[] {});

			return schedulerObject;
		} catch (Exception e) {
			SystemLogsHelper.error("创建调度器失败", e.getCause());
			e.printStackTrace();
		}

		return null;
	}

	/** 执行任务调度器里的方法 */
	private Object invokeSchedule(String methodName, Object... objects) {
		Class<?>[] clazzs = new Class[objects.length];
		for (int i = 0; i < objects.length; i++) {
			clazzs[i] = objects[i].getClass();
		}
		
		try {
			Method method = schedulerObject.getClass().getMethod(methodName,
					clazzs);
			return method.invoke(schedulerObject, objects);
		} catch (Exception e) {
			SystemLogsHelper.error("调度器执行" + methodName + "失败", e.getCause());
			e.printStackTrace();
		}
		
		return null;
	}

	/** 启动调度器 */
	public void start() {
		if (this.schedulerObject != null) {
			SystemLogsHelper.info("开始启动任务调度器.......");
			this.invokeSchedule("start", new Object[] {});
			SystemLogsHelper.info("任务调度器启动完成!");

		}
	}

	/** 暂停调度器 */

	public void pause() {
		if (this.schedulerObject != null) {
			this.invokeSchedule("standby", new Object[] {});
		}
	}

	/** 停止调度器 */

	public void stop() {
		if (this.schedulerObject != null) {
			// 加true意思是停止之前完成正在执行的 Job,false是立即停止
			this.invokeSchedule("shutdown", new Object[] {});

		}
	}

	/** 中断job,要配合Job implements InterruptableJob 使用 */

	public void interruptJob(String jobName, String groupName) {
		if (this.schedulerObject != null) {
			this
					.invokeSchedule("interrupt", new Object[] { jobName,
							groupName });
		}
	}

	/** 删除job */

	public void deleteJob(String jobName, String groupName) {
		if (this.schedulerObject != null) {
			this.invokeSchedule("deleteJob",
					new Object[] { jobName, groupName });
		}
	}
 
}

 

 

之后可对这个类进行启动等操作,也可定时操作任务调度的xml



注:

以上只能通过反射的方式调用,由于classloader的安全机制,同样的类,父classloader装载的类 和 子classloader装载的类不能互相转换。不能够用强制转换

 

http://waterdh.iteye.com/blog/520399







 

分享到:
评论

相关推荐

    Quartz任务调度-详细教程

    Quartz任务调度--详细教程,讲的非常详细

    quartz-1.6.0.jar和quartz-all-1.6.0.jar

    Quartz是Java领域的一款强大的开源任务调度框架,它允许开发者创建和管理定时任务,从而实现应用程序的自动执行功能。在给定的压缩包文件中,我们有两个版本为1.6.0的Quartz JAR包:`quartz-1.6.0.jar`和`quartz-all...

    基于Quartz.Net组件实现定时任务调度-QuartzServer.zip

    "基于Quartz.Net组件实现定时任务调度-QuartzServer.zip"这个压缩包很可能是包含了Quartz.Net的示例项目或者服务器端实现,帮助开发者了解如何在实际项目中使用Quartz.Net进行任务调度。 Quartz.Net的工作原理: 1....

    quartz-2.4.0-SNAPSHOT-distribution.tar.gz

    Quartz是Java领域的一款强大的开源任务调度框架,用于在应用程序中安排和执行周期性任务。在版本2.4.0-SNAPSHOT中,它提供了一个预发布版本的更新,这通常意味着开发者可以提前试用新功能和改进,但可能包含未解决的...

    Spring的定时调度--Quartz

    1. **依赖引入**:在Spring项目中,首先需要在pom.xml或build.gradle文件中添加Quartz和Spring的 quartz-spring 依赖。 2. **配置Quartz**:创建quartz.properties文件,配置Quartz的工作环境,如数据库连接、...

    spring任务调度(Quartz )

    首先,要在Spring中使用Quartz,你需要将`quartz-all-1.5.2.jar`等相关的Quartz库添加到项目的类路径中。这个库包含了Quartz所需的所有组件,使你可以方便地创建和管理定时任务。 在配置文件中,我们通常会创建一个...

    quartz-all-1.6.0.jar包定时任务jar

    Quartz是中国最流行的开源计划任务库之一,它允许开发者在Java应用程序中安排任务的执行。...不过,需要注意的是,随着任务数量的增加,调度器的性能和内存消耗也会上升,因此在大型系统中需要合理规划和优化任务调度。

    springboot-quartz任务调度

    Quartz则是Java领域中广泛应用的任务调度库,支持复杂的定时任务定义和执行。 1. **集成SpringBoot与Quartz** - 添加依赖:在SpringBoot的pom.xml文件中,需要引入Quartz的依赖,例如: ```xml &lt;groupId&gt;org....

    spring整合quartz动态定时任务demo-spring-quartz-demo.zip

    Quartz是另一个流行的任务调度库,它允许开发者创建和管理定时任务。当我们需要在Spring应用中实现动态定时任务时,就需要将这两者结合起来。这个"spring-quartz-demo"项目就是一个很好的示例,它展示了如何在Spring...

    Quartz.Net任务调度

    Quartz.Net是一个强大的任务调度框架,它在.NET环境中被广泛应用,尤其在需要执行定时任务的系统中。Quartz.Net的设计灵感来源于Java的Quartz库,它允许开发者灵活地定义和管理作业(Jobs)以及触发器(Triggers),...

    Quartz任务调度器

    Quartz任务调度器是一款强大的开源任务调度框架,广泛应用于Java应用程序中,用于自动化定时任务的执行。它提供了灵活的任务调度机制,使得开发者可以方便地定义、安排和执行各种任务。在与Spring框架整合后,Quartz...

    .net Quartz 任务调度平台源码

    《.NET Quartz 任务调度平台源码解析与应用》 .NET Quartz 是一款强大的任务调度框架,它为.NET开发者提供了一种高效、灵活的方式来安排和执行周期性任务。Quartz.NET 是开源项目Quartz的.NET版本,它允许开发人员...

    quartz任务调度框架简单实用小demo

    本“quartz任务调度框架简单实用小demo”旨在帮助开发者快速理解和应用Quartz。 1. **Quartz基本概念** - **Job**: 任务的基本单元,代表一个需要执行的工作。 - **Trigger**: 触发器,决定Job何时被执行。 - **...

    quartz quartz-1.8.6 dbTables 建表sql

    总之,"quartz quartz-1.8.6 dbTables" 提供了构建Quartz调度框架所需的数据库脚本,确保了任务调度的存储和恢复功能。通过理解和正确应用这些脚本,开发者可以充分利用Quartz的强大功能,创建和管理复杂的时间驱动...

    quartz 定时任务调度

    Quartz 提供了一套丰富的 API 和支持,可以方便地与 Spring 框架集成,实现灵活的定时任务调度。 在 Spring 中集成 Quartz,首先需要创建一个 Java 类作为定时任务的执行体,例如 `MyJob` 类。这个类通常包含一个...

    quartz-all-1.6.0

    在标题中提到的 "quartz-all-1.6.0" 版本,是 Quartz 框架的一个特定发行版,它包含了所有必要的组件和库,以便在 Java 环境下使用。 Quartz 主要功能包括: 1. **任务调度**:Quartz 提供了强大的 API,可以方便地...

    任务调度Quartz框 架

    【Quartz任务调度框架】 Quartz是一个开源的任务调度框架,非常适合初学者入门。它为Java开发者提供了一种高效且可控的方式来实现定时任务的调度。在各种企业应用中,任务调度的需求非常常见,例如定期清理系统垃圾...

    quartz-1.6.2 时间任务调度框架 jar 包

    spring quartz 时间任务调度框架 spring quartz 时间任务调度框架 spring quartz 时间任务调度框架

    利用Quartz实现任务调度的集群

    【Quartz任务调度集群】是Java开发中解决定时任务需求的一种高效方案,它由OpenSymphony团队开发,自2001年以来广泛应用于各种项目。Quartz的核心优势在于其灵活性和简单性,允许开发者自由定义任务触发的时间表,...

    Spring整合任务调度框架Quartz

    Spring 整合任务调度框架 Quartz 在软件开发中,任务调度框架是非常重要的一部分,它可以帮助开发者更好地管理和执行各种任务。在 Java 领域中,Quartz 是一个非常流行的任务调度框架,而 Spring 是一个非常流行的 ...

Global site tag (gtag.js) - Google Analytics