项目中要加入调度和计划任务等功能,所以选择Quartz调度插件,原先都是在S2SH上整合的。现在项目用JFinal框架,不得不说JFinal框架的定制性真好,可以自己根据项目要求进行修改,并且很节省时间。
原先当然是先找有没有JFinal的quartz插件,先是找到了JFinal-ext,里面有一个QuartzPlugin,不过因为自己比较喜欢在代码中配置调度,而且项目需求中的调度是实时性的,不是定死的。所以不太适用,所以在JFinal-ext的QuartzPlugin基础上,“抄袭”了一下,下面是我自己改的
QuartzPlugin
1import java.util.Properties; 2 3import org.quartz.Scheduler; 4import org.quartz.impl.StdSchedulerFactory; 5 6import xidian.wwf.ivc.quartz.QuartzFactory; 7import xidian.wwf.ivc.utils.PropertiesUtil; 8 9import com.jfinal.plugin.IPlugin; 10 11/** 12 * Quartz插件 13 * @author WWF 14 */ 15public class QuartzPlugin implements IPlugin{ 16 17 18 /**默认配置文件**/ 19 private String config = "quartz.properties"; 20 21 public QuartzPlugin(){ 22 23 } 24 25 public QuartzPlugin(String config){ 26 this.config = config; 27 } 28 29 @Override 30 public boolean start() { 31 try { 32 //加载配置文件 33 Properties props = PropertiesUtil.loadPropertyFile(config); 34 //实例化 35 QuartzFactory.sf = new StdSchedulerFactory(props); 36 //获取Scheduler 37 Scheduler sched = QuartzFactory.sf.getScheduler(); 38 sched.start(); 39 return true; 40 } catch (Exception e) { 41 e.printStackTrace(); 42 } 43 return false; 44 } 45 46 @Override 47 public boolean stop() { 48 try { 49 QuartzFactory.sf.getScheduler().shutdown(); 50 QuartzFactory.sf = null; 51 return true; 52 } catch (Exception e) { 53 e.printStackTrace(); 54 } 55 return false; 56 } 57 58}
QuartzFactory是我自己写的一个开始job任务的管理类,如下
1import static org.quartz.JobBuilder.newJob; 2import static org.quartz.TriggerBuilder.newTrigger; 3 4import org.quartz.Job; 5import org.quartz.JobDetail; 6import org.quartz.Scheduler; 7import org.quartz.SchedulerFactory; 8import org.quartz.SimpleTrigger; 9import org.quartz.Trigger; 10import org.quartz.TriggerKey; 11 12import xidian.wwf.ivc.utils.TimeUtil; 13 14/** 15 * QuartzFactory 16 * @author WWF 17 */ 18public class QuartzFactory { 19 20 public static SchedulerFactory sf; 21 22 /** 23 * 定时开始任务 24 * @param startTime 25 * @param id 26 * @param name 27 * @param group 28 * @param jobClass 29 */ 30 public static void startJobOnce(String startTime, int id,String name,String group,Class<? extends Job> jobClass){ 31 try { 32 Scheduler sched = sf.getScheduler(); 33 // define the job and tie it to our HelloJob class 34 JobDetail job = newJob(jobClass) 35 .withIdentity("job_"+name+"_"+id, "group_"+group+"_"+id) 36 .requestRecovery() 37 .build(); 38 job.getJobDataMap().put(group+"_"+name, id); 39 // 定时执行 40 SimpleTrigger trigger = (SimpleTrigger) newTrigger() 41 .withIdentity("trigger_"+name+"_"+id, "group_"+group+"_"+id) 42 .startAt(TimeUtil.StringToDate2(startTime)) 43 .build(); 44 45 46 sched.scheduleJob(job, trigger); 47 sched.start(); 48 } catch (Exception e) { 49 e.printStackTrace(); 50 } 51 } 52 53 /** 54 * 停止任务 55 * @param name 56 * @param group 57 * @param id 58 */ 59 public static void stopJob(String name,String group,int id){ 60 try { 61 if (sf!=null) { 62 Scheduler scheduler = sf.getScheduler(); 63 TriggerKey triggerKey = TriggerKey.triggerKey("trigger_"+name+"_"+id,"group_"+ group+"_"+id); 64 Trigger trigger = scheduler.getTrigger(triggerKey); 65 if (trigger!=null) { 66 scheduler.pauseTrigger(triggerKey); 67 scheduler.unscheduleJob(triggerKey); 68 scheduler.deleteJob(trigger.getJobKey()); 69 } 70 } 71 } catch (Exception e) { 72 e.printStackTrace(); 73 } 74 } 75 76 77 78}
因为有时候服务器维护,会关闭tomcat,所以我把调度任务存入到数据库中,可以中断回复,下面是我的quartz.properties配置文件和数据库连接ConnectionProvider
quartz.properties
1#================================================== 2# 配置实例名和id 3#================================================== 4org.quartz.scheduler.instanceName = myScheduler 5org.quartz.scheduler.instanceId: my 6org.quartz.scheduler.skipUpdateCheck: true 7 8#================================================== 9# 配置线程池 10#================================================== 11org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool 12org.quartz.threadPool.threadCount: 5 13org.quartz.threadPool.threadPriority: 5 14 15#================================================== 16# 配置JobStore 17#================================================== 18org.quartz.jobStore.misfireThreshold: 600000 19 20org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX 21org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate 22org.quartz.jobStore.useProperties=false 23org.quartz.jobStore.dataSource=my 24org.quartz.jobStore.tablePrefix=QRTZ_ 25org.quartz.jobStore.isClustered=true 26 27#================================================== 28# 配置数据库 29#================================================== 30org.quartz.dataSource.my.connectionProvider.class = QuartzConnectionProvider
QuartzConnectionProvider
1import java.sql.Connection; 2import java.sql.SQLException; 3import java.util.Properties; 4 5import org.quartz.utils.ConnectionProvider; 6 7import xidian.wwf.ivc.utils.PropertiesUtil; 8 9import com.alibaba.druid.filter.stat.StatFilter; 10import com.alibaba.druid.wall.WallFilter; 11import com.jfinal.plugin.druid.DruidPlugin; 12 13/** 14 * 自定义QuartzConnectionProvider 15 * @author WWF 16 */ 17public class QuartzConnectionProvider implements ConnectionProvider{ 18 19 private static final String DB_CONFIG="databaseConfig.properties"; 20 private DruidPlugin druidPlugin; 21 22 @Override 23 public Connection getConnection() throws SQLException { 24 return druidPlugin.getDataSource().getConnection(); 25 } 26 27 @Override 28 public void initialize() throws SQLException { 29 Properties properties = PropertiesUtil.loadPropertyFile(DB_CONFIG); 30 druidPlugin = new DruidPlugin( 31 properties.getProperty("jdbcUrl"), 32 properties.getProperty("user"), 33 properties.getProperty("password"), 34 properties.getProperty("jdbcDriverClass")); 35 // StatFilter提供JDBC层的统计信息 36 druidPlugin.addFilter(new StatFilter()); 37 // WallFilter的功能是防御SQL注入攻击 38 WallFilter wallFilter = new WallFilter(); 39 wallFilter.setDbType("mysql"); 40 druidPlugin.addFilter(wallFilter); 41 druidPlugin.start(); 42 } 43 44 @Override 45 public void shutdown() throws SQLException { 46 druidPlugin.stop(); 47 } 48 49}
QuartzConnectionProvider中使用了DruidPlugin,动态加载数据库配置文件,数据库更换只需要修改数据库配置文件即可
最后,新建一个TestJob
1import org.quartz.Job; 2import org.quartz.JobExecutionContext; 3import org.quartz.JobExecutionException; 4 5import xidian.wwf.ivc.utils.TimeUtil; 6 7public class TestJob implements Job{ 8 9 public TestJob(){ 10 } 11 12 @Override 13 public void execute(JobExecutionContext arg0) throws JobExecutionException { 14 System.out.println("开始时间="+TimeUtil.getTimeAll()); 15 try { 16 //JobDataMap dataMap= arg0.getJobDetail().getJobDataMap(); 17 System.out.println("哇哈哈"); 18 } catch (Exception e) { 19 e.printStackTrace(); 20 } 21 System.out.println("结束时间="+TimeUtil.getTimeAll()); 22 } 23 24 25}
在afterJFinalStart中新建测试任务
1//测试quartz 2String startTime = "2014-03-09 09:54:00"; 3QuartzFactory.startJobOnce(startTime, 5, "test", "testgroup", TestJob.class);
到点了就执行TestJob了。大家还可以根据需要,在QuartzFactory中添加间隔定时调度等,因为我项目就一个定点调度,所以基本都是执行一次即可。
写的不好,大家勿喷!