Quartz教程:深入Job与JobDetail

在前面部分,我们知道Job中定义了实际的业务逻辑,而JobDetail包含Job相关的配置信息。在Quartz中,每次Scheduler执行Job时,在调用其execute()方法之前,它需要先根据JobDetail提供的Job类型创建一个Job class的实例,在任务执行完以后,Job class的实例会被丢弃,Jvm的垃圾回收器会将它们回收。

因此编写Job的具体实现时,需要注意:(1) 它必须具有一个无参数的构造函数;(2) 它不应该有静态数据类型,因为每次Job执行完以后便被回收,因此在多次执行时静态数据没法被维护。

Keep moving,在JobDetail中有这么一个成员JobDataMap,JobDataMap是Java Map接口的具体实现,并添加了一些便利的方法用于存储与读取原生类型数据,里面包含了当Job实例运行时,你希望提供给它的所有数据对象。

可以借助JobDataMap为Job实例提供属性/配置,可以通过它来追踪Job的执行状态等等。对于第一种情况,可以在创建Job时,添加JobDataMap数据,在Job的execute()中获取数据,第二种,则可以在Listener中通过获取JobDataMap中存储的状态数据追踪Job的执行状态。

按例,一个简单的例子:

// 创建Job的实例
JobDetail jobIns = JobBuilder.newJob(SimpleJob.class).withIdentity(
		"simpleJob", "group1").usingJobData("domain",
		"www.jmatrix.org").usingJobData("rank", "求别提~~~").build();

Job实现:

public void execute(JobExecutionContext context)
			throws JobExecutionException {
	System.out.println("开始!");

	//……JobDataMap
	JobDataMap dataMap = context.getJobDetail().getJobDataMap();
	System.out.println("域名 : "+dataMap.getString("domain"));
	System.out.println("排名 : "+dataMap.getString("rank"));

	System.out.println("结束!");
}

完成了这些工作,还需决定如何存储Job的数据,Quartz提供了JobStore接口来做这件事,如果你决定将Job数据保存在内存中,则可以使用RAMJobStore,它的优点是速度快,缺点是一旦机器挂了,Job相关的数据也丢失了,如果要采用数据库来存储Job数据,可以使用JobStoreTX或JobStoreCMT,这取决于你采用的事务管理方式,使用RAMJobStore的话配置很简单,只需配置org.quartz.jobStore.class即可,如果使用数据库存储,则还需要配置driverDelegate,tablePrefix及dataSource,driverDelegate一般情况下使用StdJDBCDelegate(MySQL便可使用这个),特殊的可以使用Quartz提供的相关delegate,请查看jar包,一般命名就说明了一切。TablePrefix是你的数据库表前缀,创建数据库的sql文件可以在docs\dbTables目录下找到。最后的数据源dataSource就有点麻烦,Quartz为用户提供了三种创建dataSource的方式:

  1. 配置相关的数据库属性(driverClass,url,username,password等),让Quartz为你创建dataSource。
  2. 通过jndi使用你应用服务器管理的dataSource。
  3. 通过实现org.quartz.utils.ConnectionProvider定制自己的datasource。

前面两种都是依据datasource的名称为其配置相关的属性,具体有哪些属性可直接参考Quartz的文档。

下面说说最后一种,我们需要配置:

org.quartz.dataSource.dbcpDS.connectionProvider.class=cn.ds.vertical.core.service.mail.DbcpConnectionProvider

这样Quartz才能找到自定义的ConnectionProvider实现,DbcpConnectionProvider是我模仿Quartz提供的默认ConnectionProvider实现实现的,只是提供一种思路,Quartz使用的c3p0,而DbcpConnectionProvider使用DBCP作为DataSource实现。

public class DbcpConnectionProvider implements ConnectionProvider {

	private BasicDataSource basicDataSource;

	public DbcpConnectionProvider(){
		initialize();
	}

	public Connection getConnection() throws SQLException {
		return this.basicDataSource.getConnection();
	}

	public void shutdown() throws SQLException {
		this.basicDataSource.close();
	}

	private void initialize(){
		String driverClassName = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/quartz";
		String username = "root";
		String password = "123456";

		this.basicDataSource = new BasicDataSource();
		this.basicDataSource.setDriverClassName(driverClassName);
		this.basicDataSource.setUrl(url);
		this.basicDataSource.setUsername(username);
		this.basicDataSource.setPassword(password);

		this.basicDataSource.setTestWhileIdle(true);
	}
}

 

如果未说明,本Blog中文章皆为原创文章,请尊重他人劳动,转载请注明: 转载自jmatrix

本文链接地址: Quartz教程:深入Job与JobDetail

(注:一般引用了,我都会添加引用,如果有侵权的请联系我)



This entry was posted in Java and tagged . Bookmark the permalink. Follow any comments here with the RSS feed for this post. Trackbacks are closed, but you can post a comment.