项目中要加入调度和计划任务等功能,所以选择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中添加间隔定时调度等,因为我项目就一个定点调度,所以基本都是执行一次即可。
写的不好,大家勿喷!