文档章节

JFinal 整合Quartz

超级大富
 超级大富
发布于 2014/03/09 20:13
字数 853
阅读 2534
收藏 99

       项目中要加入调度和计划任务等功能,所以选择Quartz调度插件,原先都是在S2SH上整合的。现在项目用JFinal框架,不得不说JFinal框架的定制性真好,可以自己根据项目要求进行修改,并且很节省时间。

        原先当然是先找有没有JFinal的quartz插件,先是找到了JFinal-ext,里面有一个QuartzPlugin,不过因为自己比较喜欢在代码中配置调度,而且项目需求中的调度是实时性的,不是定死的。所以不太适用,所以在JFinal-ext的QuartzPlugin基础上,“抄袭”了一下,下面是我自己改的

QuartzPlugin

import java.util.Properties;

import org.quartz.Scheduler;
import org.quartz.impl.StdSchedulerFactory;

import xidian.wwf.ivc.quartz.QuartzFactory;
import xidian.wwf.ivc.utils.PropertiesUtil;

import com.jfinal.plugin.IPlugin;

/**
 * Quartz插件
 * @author WWF
 */
public class QuartzPlugin implements IPlugin{
	
	
	/**默认配置文件**/
	private String config = "quartz.properties";
	
	public QuartzPlugin(){
		
	}
	
	public QuartzPlugin(String config){
		this.config = config;
	}

	@Override
	public boolean start() {
		try {
		    //加载配置文件
		    Properties props = PropertiesUtil.loadPropertyFile(config);
		    //实例化
		    QuartzFactory.sf = new StdSchedulerFactory(props);
		    //获取Scheduler
		    Scheduler sched = QuartzFactory.sf.getScheduler();
        	    sched.start();
        	    return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean stop() {
		try {
			QuartzFactory.sf.getScheduler().shutdown();
			QuartzFactory.sf = null;
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

}

QuartzFactory是我自己写的一个开始job任务的管理类,如下

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerKey;

import xidian.wwf.ivc.utils.TimeUtil;

/**
 * QuartzFactory 
 * @author WWF
 */
public class QuartzFactory {
	
	public static SchedulerFactory sf;
	
	/**
	 * 定时开始任务
	 * @param startTime
	 * @param id
	 * @param name
	 * @param group
	 * @param jobClass
	 */
	public static void startJobOnce(String startTime, int id,String name,String group,Class<? extends Job> jobClass){
		try {
			Scheduler sched = sf.getScheduler();
			// define the job and tie it to our HelloJob class
			  JobDetail job = newJob(jobClass)
			      .withIdentity("job_"+name+"_"+id, "group_"+group+"_"+id)
			      .requestRecovery()
			      .build();
			  job.getJobDataMap().put(group+"_"+name, id);
			  // 定时执行
			  SimpleTrigger trigger = (SimpleTrigger) newTrigger()
			      .withIdentity("trigger_"+name+"_"+id, "group_"+group+"_"+id)
			      .startAt(TimeUtil.StringToDate2(startTime))
			      .build();
			  

			  sched.scheduleJob(job, trigger);
			  sched.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 停止任务
	 * @param name
	 * @param group
	 * @param id
	 */
	public static void stopJob(String name,String group,int id){
		try {
			if (sf!=null) {
				Scheduler scheduler = sf.getScheduler();
				TriggerKey triggerKey = TriggerKey.triggerKey("trigger_"+name+"_"+id,"group_"+ group+"_"+id);
				Trigger trigger = scheduler.getTrigger(triggerKey);
				if (trigger!=null) {
					scheduler.pauseTrigger(triggerKey);
					scheduler.unscheduleJob(triggerKey);
					scheduler.deleteJob(trigger.getJobKey());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}



}

因为有时候服务器维护,会关闭tomcat,所以我把调度任务存入到数据库中,可以中断回复,下面是我的quartz.properties配置文件和数据库连接ConnectionProvider

quartz.properties

#==================================================
# 配置实例名和id  
#==================================================
org.quartz.scheduler.instanceName = myScheduler
org.quartz.scheduler.instanceId: my
org.quartz.scheduler.skipUpdateCheck: true

#==================================================
# 配置线程池  
#==================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 5
org.quartz.threadPool.threadPriority: 5

#==================================================
# 配置JobStore 
#==================================================
org.quartz.jobStore.misfireThreshold: 600000

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.dataSource=my
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true

#==================================================
# 配置数据库
#==================================================
org.quartz.dataSource.my.connectionProvider.class = QuartzConnectionProvider

QuartzConnectionProvider

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import org.quartz.utils.ConnectionProvider;

import xidian.wwf.ivc.utils.PropertiesUtil;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.plugin.druid.DruidPlugin;

/**
 * 自定义QuartzConnectionProvider
 * @author WWF
 */
public class QuartzConnectionProvider implements ConnectionProvider{
	
	private static final String DB_CONFIG="databaseConfig.properties";
	private DruidPlugin druidPlugin;

	@Override
	public Connection getConnection() throws SQLException {
		return druidPlugin.getDataSource().getConnection();
	}

	@Override
	public void initialize() throws SQLException {
		Properties properties = PropertiesUtil.loadPropertyFile(DB_CONFIG);
		druidPlugin = new DruidPlugin(
				properties.getProperty("jdbcUrl"),
				properties.getProperty("user"),
				properties.getProperty("password"),
				properties.getProperty("jdbcDriverClass"));
		// StatFilter提供JDBC层的统计信息
		druidPlugin.addFilter(new StatFilter());
		// WallFilter的功能是防御SQL注入攻击
		WallFilter wallFilter = new WallFilter();
		wallFilter.setDbType("mysql");
		druidPlugin.addFilter(wallFilter);
		druidPlugin.start();
	}

	@Override
	public void shutdown() throws SQLException {
		druidPlugin.stop();
	}

}

QuartzConnectionProvider中使用了DruidPlugin,动态加载数据库配置文件,数据库更换只需要修改数据库配置文件即可

最后,新建一个TestJob

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

import xidian.wwf.ivc.utils.TimeUtil;

public class TestJob implements Job{
	
	public TestJob(){
	}

	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		System.out.println("开始时间="+TimeUtil.getTimeAll());
		try {
			//JobDataMap dataMap= arg0.getJobDetail().getJobDataMap();
			System.out.println("哇哈哈");
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("结束时间="+TimeUtil.getTimeAll());
	}
	

}

在afterJFinalStart中新建测试任务

//测试quartz
String startTime = "2014-03-09 09:54:00";
QuartzFactory.startJobOnce(startTime, 5, "test", "testgroup", TestJob.class);

到点了就执行TestJob了。大家还可以根据需要,在QuartzFactory中添加间隔定时调度等,因为我项目就一个定点调度,所以基本都是执行一次即可。

写的不好,大家勿喷!

© 著作权归作者所有

超级大富

超级大富

粉丝 49
博文 20
码字总数 26710
作品 1
温州
技术主管
私信 提问
加载中

评论(20)

没想好
这是怎么回事
org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'group_testgroup_5.job_test_5', because one already exists with this identification.
超级大富
超级大富 博主

引用来自“孤单时会想你”的评论

博主还在么?我有个问题搞了一下午了 没搞出来 囧~ 我照着你的做的 有点问题不接,求教啊!
用JDBCJobStroe 持久化,第一次,关闭服务器 后数据库里有数据 有保存job的相关信息,我重新启动服务器,遍历StdSchedulerFactory.getDefaultScheduler().checkExists(triggerKey) 宕机之前的job在里面,
我改怎么恢复呢?
sched.resumeJob(trigger.getJobKey());
sched.triggerJob(trigger.getJobKey());
sched.rescheduleJob(triggerKey,trigger);
我尝试了 都没效果 哎~就是不运行
我参考过这个博客http://ygydaiaq-gmail-com.iteye.com/blog/1729626
超级大富
超级大富 博主

引用来自“孤单时会想你”的评论

博主还在么?我有个问题搞了一下午了 没搞出来 囧~ 我照着你的做的 有点问题不接,求教啊!
用JDBCJobStroe 持久化,第一次,关闭服务器 后数据库里有数据 有保存job的相关信息,我重新启动服务器,遍历StdSchedulerFactory.getDefaultScheduler().checkExists(triggerKey) 宕机之前的job在里面,
我改怎么恢复呢?
sched.resumeJob(trigger.getJobKey());
sched.triggerJob(trigger.getJobKey());
sched.rescheduleJob(triggerKey,trigger);
我尝试了 都没效果 哎~就是不运行
服务器重启的时候会自动恢复调度任务的。
孤单时会想你
孤单时会想你
博主qq多少,望进步一交流 多谢!
孤单时会想你
孤单时会想你
博主还在么?我有个问题搞了一下午了 没搞出来 囧~ 我照着你的做的 有点问题不接,求教啊!
用JDBCJobStroe 持久化,第一次,关闭服务器 后数据库里有数据 有保存job的相关信息,我重新启动服务器,遍历StdSchedulerFactory.getDefaultScheduler().checkExists(triggerKey) 宕机之前的job在里面,
我改怎么恢复呢?
sched.resumeJob(trigger.getJobKey());
sched.triggerJob(trigger.getJobKey());
sched.rescheduleJob(triggerKey,trigger);
我尝试了 都没效果 哎~就是不运行
超级大富
超级大富 博主

引用来自“孤单时会想你”的评论

#==================================================
# 配置数据库
#==================================================
org.quartz.dataSource.my.connectionProvider.class = QuartzConnectionProvider
这里要写全路径 如com.a.b.c.QuartzConnectionProvider
嗯,是要写全,我把前面的包名删掉了,为了不泄密,你懂得
超级大富
超级大富 博主

引用来自“孤单时会想你”的评论

感谢博主分享。。
给博主补充一句: quartz的配置文件 默认文件名为 quartz.properties 默认在 quartz.版本号.jar 里的 org.quartz包下面,对于喜欢自定义路的兄弟(我就是 喜欢把各种配置文件放在一个专门文件夹里 如:conf) 可以直接自定义的。
直接设置就是:
System.setProperty("org.quartz.properties","含文件名自定义全路径");
文件名可以自定义 如:c:/myconfig.properties
具体可以参考 org.quartz.impl.StdSchedulerFactory 以下为寻找配置文件的部分源码:
public static final String PROPERTIES_FILE = "org.quartz.properties";
String requestedFile = System.getProperty(PROPERTIES_FILE);
String propFileName = requestedFile != null ? requestedFile: "quartz.properties";
File propFile = new File(propFileName);
。。。。。。
//加载配置文件 Properties props = PropertiesUtil.loadPropertyFile(config); 这个已经是加载自定义配置文件了
孤单时会想你
孤单时会想你
#==================================================
# 配置数据库
#==================================================
org.quartz.dataSource.my.connectionProvider.class = QuartzConnectionProvider
这里要写全路径 如com.a.b.c.QuartzConnectionProvider
孤单时会想你
孤单时会想你
感谢博主分享。。
给博主补充一句: quartz的配置文件 默认文件名为 quartz.properties 默认在 quartz.版本号.jar 里的 org.quartz包下面,对于喜欢自定义路的兄弟(我就是 喜欢把各种配置文件放在一个专门文件夹里 如:conf) 可以直接自定义的。
直接设置就是:
System.setProperty("org.quartz.properties","含文件名自定义全路径");
文件名可以自定义 如:c:/myconfig.properties
具体可以参考 org.quartz.impl.StdSchedulerFactory 以下为寻找配置文件的部分源码:
public static final String PROPERTIES_FILE = "org.quartz.properties";
String requestedFile = System.getProperty(PROPERTIES_FILE);
String propFileName = requestedFile != null ? requestedFile: "quartz.properties";
File propFile = new File(propFileName);
。。。。。。
泥瓦匠BYSocket
泥瓦匠BYSocket
大富写的 不错啊,最近我也搞这个 哈哈
JFinal Extensions 1.1 发布,JFinal 扩展

Jfinal-ext是对java极速web框架 jfinal 的一个扩充,主要利用jfinal的plugin机制集成各种第三方框架,像spring一样,简化开发者的学习应用成本,使用时请将jfinal.jar先引入工程。 changelo...

绝望的八皮
2012/10/26
705
12
Jfinal集成quartz后数据库连接问题

@JFinal 你好,想跟你请教个问题: Jfinal目前还没有光放集成quartz的插件吗?在oschina上有一个地址是http://my.oschina.net/b1412/blog/68082 但是使用这个在执行job的时候需要使用db.find...

山东-小木
2013/08/24
1K
3
想问下如何给jfinal定时器quartz加上事物

@JFinal 你好,想跟你请教个问题:想问下如何给jfinal的扩展的定时器quartz里面加上事物。我现在是在execute方法上面加了tx.class注解。发现quartz一旦执行到runtime异常就重新开始定时器任务...

loda0128
2014/11/11
1K
3
jfinal中对分布式事务的支持

@JFinal 你好,想跟你请教个问题:在实际项目过程中,用到了quartz组件。为了保证quartz组件中任务额事务与service层事务在同一事务控制中,使用配置文件将quartz组件的事务控制交由应用服务...

qiran
2015/06/24
1K
1
quartz和jfinal如何做定时任务的动态控制?比如任务暂停啊,添加啊之类。或者其他的办法?

@JFinal 你好,想跟你请教个问题:quartz和jfinal如何做定时任务的动态控制?比如任务暂停啊,添加啊之类。或者其他的办法,绝望的扒皮分享的那个需要去配置cron表达式,很死板啊...

azura111
2016/07/12
1K
4

没有更多内容

加载失败,请刷新页面

加载更多

计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
6
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
6
0
【技术分享】TestFlight测试的流程文档

上架基本需求资料 1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程) 2、开发好的APP 通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestF...

qtb999
昨天
10
0
再见 Spring Boot 1.X,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维...

Java技术剑
昨天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部