实现了spring3.1x与quartz2.2.1两种技术配合,以spring管理quartz信息。
quartz实现的是用数据库持久保存任务调度信息,对任务进行创建、暂停、重启、删除、清除等动态执行各种方法。
不多说,直接代码
spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="applicationContextSchedulerContextKey" value="applicationContextKey" /> <property name="autoStartup" value="true" /> <property name="configLocation" value="classpath:quartz.properties"/> </bean> </beans>
quartz.properties
org.quartz.scheduler.instanceName: TestScheduler org.quartz.scheduler.instanceId: instance_one org.quartz.scheduler.skipUpdateCheck: true #============================================================================ # Configure ThreadPool #============================================================================ org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount: 5 org.quartz.threadPool.threadPriority: 5 #============================================================================ # Configure JobStore #============================================================================ org.quartz.jobStore.misfireThreshold: 60000 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=myDS org.quartz.jobStore.tablePrefix=QRTZ_ org.quartz.jobStore.isClustered=true
逻辑类
import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.DateBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.SimpleTrigger; import org.quartz.TriggerBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.dream.quartz.job.SimpleRecoveryJob; public class DbQuartzService { //log4j private static Logger _log = LoggerFactory.getLogger(DbQuartzService.class); /** * * @param inClearJobs 是否清空任务 * @param inScheduleJobs * @param sched Spring-quartz.xml中获取的调度器工厂类,由spring实现 * @throws Exception */ public void executeJob(boolean inClearJobs, boolean inScheduleJobs,Scheduler sched) throws Exception { //使用quartz2.2.1自带的调度器工厂类 // SchedulerFactory sf = new StdSchedulerFactory(); // Scheduler sched = sf.getScheduler(); if (inClearJobs) { _log.warn("***** Deleting existing jobs/triggers *****"); sched.clear(); } _log.info("------- Initialization Complete -----------"); JobDetail cornJob = null; JobDetail simpleJob = null; if (inScheduleJobs) { _log.info("------- Scheduling Jobs ------------------"); String schedId = sched.getSchedulerInstanceId(); int count = 1; cornJob = JobBuilder.newJob(SimpleRecoveryJob.class).withIdentity("job_" + count, schedId).requestRecovery().build(); // JobDetail jobDetail = new JobDetail("job_" + count, schedId, SimpleRecoveryJob.class); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?"); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job_" + count, schedId).withSchedule(scheduleBuilder).build(); _log.info(cornJob.getKey()+" 表达式调度触发器"); sched.scheduleJob(cornJob, cronTrigger); count++; simpleJob = JobBuilder.newJob(SimpleRecoveryJob.class).withIdentity("job_" + count, schedId).requestRecovery().build(); SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().withIdentity("triger_" + count, schedId) .startAt(DateBuilder.futureDate(2, DateBuilder.IntervalUnit.SECOND)) .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withRepeatCount(20)//重复20次 // repeatForever() 一直重复执行 .withIntervalInSeconds(3) ).build();//每5秒重复一次 _log.info(simpleJob.getKey() + "简单触发器"); sched.scheduleJob(simpleJob, trigger); } _log.info("------- Starting Scheduler ---------------"); sched.start(); _log.info("------- Started Scheduler ----------------"); _log.info("------- Waiting for one hour... ----------"); try { //休眠1个小时,以便可以充分的看到调度器的执行 Thread.sleep(10000); sched.pauseJob(simpleJob.getKey());//暂停调度器执行 Thread.sleep(10000); sched.resumeJob(simpleJob.getKey());//重新启动暂度器 Thread.sleep(10000); sched.deleteJob(simpleJob.getKey()); Thread.sleep(3600000L); } catch (Exception e) { } _log.info("------- Shutting Down --------------------"); sched.shutdown(); _log.info("------- Shutdown Complete ----------------"); } }
Job类
import java.util.Date; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SimpleRecoveryJob implements Job{ private static Logger _log = LoggerFactory.getLogger(SimpleRecoveryJob.class); private static final String COUNT = "count"; public void execute(JobExecutionContext context) throws JobExecutionException { JobKey jobKey = context.getJobDetail().getKey(); if (context.isRecovering()) _log.info("SimpleRecoveryJob: " + jobKey + " RECOVERING at " + new Date()); else { _log.info("SimpleRecoveryJob: " + jobKey + " starting at " + new Date()); } long delay = 10000L; try { Thread.sleep(delay); } catch (Exception e) { } JobDataMap data = context.getJobDetail().getJobDataMap(); int count; if (data.containsKey("count")) count = data.getInt("count"); else { count = 0; } count++; data.put("count", count); _log.info("SimpleRecoveryJob: " + jobKey + " done at " + new Date() + "\n Execution #" + count); } }
测试类
import org.junit.Test; import org.junit.runner.RunWith; import org.quartz.Scheduler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.dream.quartz.service.DbQuartzService; @RunWith(SpringJUnit4ClassRunner.class) //使用junit4进行测试 @ContextConfiguration({"/spring-quartz.xml"}) //加载配置文件 public class DbQuartzTest { @Autowired // 注入 private Scheduler schedulerFactoryBean; @Test public void executeQuartzTest() { DbQuartzService quartzService = new DbQuartzService(); try { // ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml"); //加载单个配置文件 // String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"}; // ApplicationContext ctx = new FileSystemXmlApplicationContext(locations ); //加载单个配置文件 //上述两种方式,亦可以用ClassPathXmlApplicationContext替代FileSystemXmlApplicationContext // ServletContext servletContext = request.getSession().getServletContext(); // ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext); boolean clearJobs = true; boolean scheduleJobs = true; quartzService.executeJob(clearJobs,scheduleJobs,schedulerFactoryBean); } catch (Exception e) { e.printStackTrace(); } } }