本文内容 通过xml配置一个调度器Scheduler,所有的任务通过该调度器来进行调度,结合官方提供的数据结构以及调度实现来达到前端控制定时器的目的。
调度器Scheduler的作用 调度器是Quartz的核心组成部分,其作用是调度Job能够被Trigger触发,是Quartz的驱动。
调度器的创建 Scheduler的实现类有以下几个:
RemoteScheduler: 远程调度器; 
StdScheduler:默认标准调度器(最为常用的); 
RemoteMBeanScheduler:抽象类,
JBoss4RMIRemoteMBeanScheduler:是抽象类RemoteMBeanScheduler 的实现类 
 
 
StdSchedulerFactory;
使用一组参数(java.util.Properties)来创建和初始化Quartz调度器; 
配置参数一般在quartz.properties中 
调用getScheduler方法就能创建和初始化调度器对象; 
通过new StdSchedulerFactory().getScheduler(); 来获取调度器。 
 
 
DirectSchedulerFactory; 
 
定时器创建以后,可以进行增加、删除以及显示Job和Trigger,对Job进行暂停/恢复等操作,调用了.start()方法后,Scheduler才正式开始执行Job和Trigger;
StdSchedulerFactory StdSchedulerFactory依赖于一系列属性决定如何产生Scheduler,提供配置信息的方式如下:
通过java.util.Properties属性实例; 
通过外部属性文件提供; 
通过含有属性文件内容的java.io.InputStream提供; 
 
1 2 3 4 5 6 7         factory.initialize(); scheduler = factory.getScheduler("quartzScheduler" ); 
前端控制定时器暂停、恢复等核心方法 原理:配置定时器项目默认调度器名字,并结合quartz官方提供的表结构以及自动从数据库加载定时器配置的机制,使用调度器Scheduler的几个核心方法结合数据库配置达到使用前端界面控制定时器恢复、执行等操作。
void start(); // 启动 
void standby();// 挂起 
void shutdown();// 关闭 
void shutdown(true); //  等待所有正在执行的job执行完毕之后,再关闭scheduler; 
 
暂停定时器核心方法 修改数据库的执行器状态 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Override public  Message updateJobStatus (QuartzJobInfo job)  {    QuartzTriggers  triggers  =  new  QuartzTriggers ();     triggers.setSchedName(job.getSchedName());     triggers.setTriggerGroup(job.getTriggerGroup());     triggers.setTriggerName(job.getTriggerName());     triggers.setTriggerState(job.getTriggerState());     quartzTriggersDao.updateByPrimaryKeySelective(triggers);     if  (QRTZ_TRIGGER_STATUS_WAITING.equals(job.getTriggerState())) {         quartzManager.resumeJob(job.getJobName(), job.getJobGroup());     } else  {         quartzManager.pauseJob(job.getJobName(), job.getJobGroup());     }     return  Message.success(); } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16      public  void  pauseJob (String jobName, String jobGroupName)  {    JobKey  jobKey  =  JobKey.jobKey(jobName, jobGroupName);     try  {         scheduler.pauseJob(jobKey);     } catch  (SchedulerException e) {         throw  new  BusinessException ("暂停任务["  + jobGroupName + SPLIT_DOT + jobName + "]中出现异常!" , e);     } catch  (IllegalArgumentException e) {         throw  new  BusinessException ("暂停任务["  + jobGroupName + SPLIT_DOT + jobName + "]中出现异常!" , e);     } } 
恢复定时器核心方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  void  resumeJob (String jobName, String jobGroupName)  {    JobKey  jobKey  =  JobKey.jobKey(jobName, jobGroupName);     try  {         scheduler.resumeJob(jobKey);     } catch  (SchedulerException e) {         throw  new  BusinessException ("恢复任务["  + jobGroupName + SPLIT_DOT + jobName + "]中出现异常!" , e);     } } 
效果 
回顾 定时器配置:SimpleTrigger和CronTrigger spring-servlet.xml 中添加配置,用于托付给spring来管理;
配置JobDetail; 
配置Trigger; 
配置Scheduler; 
MethodInvokingJobDetailFactoryBean 
JobDetailFactoryBean:可以传入参数jobDataMap;比较灵活; 
extends QuartzJobBean 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <description > Quartz定时器配置</description > <bean  id ="lxJobDetail"  class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >          <property  name ="targetObject"  ref ="lxJobDetailBean" />           <property  name ="targetMethod"  value ="init" />  </bean > <bean  id ="lxJobDetailBean1"  class ="org.springframework.scheduling.quartz.JobDetailFactoryBean" >     <property  name ="jobClass"  value ="com.weyoung.platform.quartz.schedule.LxQuartzJobBean" />           <property  name ="jobDataMap" >          <map >              <entry  key ="anotherBean"  value-ref ="anotherBean" />          </map >      </property >      <property  name ="durability"  value ="true" />  </bean > <bean  id ="lxSimpleTrigger"  class ="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean" >     <property  name ="jobDetail"  ref ="lxJobDetail" />      <property  name ="startDelay"  value ="1000" />      <property  name ="repeatInterval"  value ="2000" />  </bean > <bean  id ="lxCronTrigger"  class ="org.springframework.scheduling.quartz.CronTriggerFactoryBean" >     <property  name ="jobDetail"  ref ="lxJobDetailBean1" />      <property  name ="cronExpression"  value ="0/5 * * ? * *" />  </bean > <bean  id ="lxQuartzScheduler"  class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >     <property  name ="jobDetails" >          <list >              <ref  bean ="lxJobDetail" />              <ref  bean ="lxJobDetailBean1" />          </list >      </property >      <property  name ="triggers" >          <list >              <ref  bean ="lxSimpleTrigger" />              <ref  bean ="lxCronTrigger" />          </list >      </property >  </bean > 
其中,定义的类lxJobDetailBean、lxJobDetailBean1、anotherBean代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package  com.weyoung.platform.quartz.schedule;import  org.slf4j.Logger;import  org.slf4j.LoggerFactory;import  org.springframework.stereotype.Component;import  java.text.SimpleDateFormat;import  java.util.Date;@Component("lxJobDetailBean") public  class  LxJobDetailBean  {    private  static  final  Logger  LOGGER  =  LoggerFactory.getLogger(LxJobDetailBean.class);     public  void  init ()  {         Date  date  =  new  Date ();         SimpleDateFormat  sdf  =  new  SimpleDateFormat ("yyyy-MM-dd hh:mm:ss" );         LOGGER.info("-----------lxJobDetailBean.init-----------"  + sdf.format(date));     } } 
LxQuartzJobBean.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package  com.weyoung.platform.quartz.schedule;import  com.weyoung.platform.quartz.entity.AnotherBean;import  org.quartz.JobExecutionContext;import  org.quartz.JobExecutionException;import  org.slf4j.Logger;import  org.slf4j.LoggerFactory;import  org.springframework.scheduling.quartz.QuartzJobBean;import  java.text.SimpleDateFormat;import  java.util.Date;public  class  LxQuartzJobBean  extends  QuartzJobBean  {         private  AnotherBean anotherBean;     private  static  final  Logger  LOGGER  =  LoggerFactory.getLogger(LxQuartzJobBean.class);          @Override      protected  void  executeInternal (JobExecutionContext jobExecutionContext)  throws  JobExecutionException {         Date  date  =  new  Date ();         SimpleDateFormat  sdf  =  new  SimpleDateFormat ("yyyy-MM-dd hh:mm:ss" );         LOGGER.info("---------LxQuartzJobBean.executeInternal---------"  + sdf.format(date));     }     public  void  setAnotherBean (AnotherBean anotherBean)  {         this .anotherBean = anotherBean;     } } 
AnotherBean.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  com.weyoung.platform.quartz.entity;import  org.springframework.stereotype.Component;@Component("anotherBean") public  class  AnotherBean  {    public  void  someMessage  ()  {     } } 
Quartz中作业存储方式 
RAMJobStore:作业、触发器、调度信息存储在内存中,这种方式存取速度比较快,但是如果定时器项目重启或者崩溃的话,存储的信息都会丢失; 
JDBC作业存储:作业、触发器、调度信息存储在数据库中,支持事务,支持集群; 
 
前面的笔记里面记录了Quartz官方提供的表结构及创建脚本等,使用该脚本创建数据库;
修改调度器信息及使用quartz.propertie文件配置 我的项目暂时是把定时器放在项目主程序中,也是使用同一个数据库,当然也可以分开。如果需要自己配置数据库的话,在quartz.properties中配置就行。spring-quartz.xml配置如下:
1 2 3 4 5 6 7 8 9 10 <bean  id ="lxQuartzScheduler"  class ="org.springframework.scheduling.quartz.SchedulerFactoryBean" >          <property  name ="dataSource"  ref ="masterDataSource" />      <property  name ="overwriteExistingJobs"  value ="true" />      <property  name ="autoStartup"  value ="true" />      <property  name ="startupDelay"  value ="20" />            <property  name ="configLocation"  value ="classpath:config/quartz.properties" />  </bean > 
quartz.properties文件的配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 org.quartz.scheduler.instanceName =lxQuartzScheduler org.quartz.scheduler.instanceid =AUTO org.quartz.scheduler.rmi.export =false org.quartz.scheduler.rmi.proxy =false org.quartz.scheduler.wrapJobExecutionInUserTransaction =false org.quartz.threadPool.class =org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount =10 org.quartz.threadPool.threadPriority =5 =========================================================================== 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.tablePrefix  = QRTZ_ org.quartz.plugin.triggHistory.class =org.quartz.plugins.history.LoggingTriggerHistoryPlugin   org.quartz.plugin.triggHistory.triggerFiredMessage =Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}   org.quartz.plugin.triggHistory.triggerCompleteMessage =Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}   
qrtz_triggers表中的字段特别解析: MISFIRE_INSTR:Misfire处理规则: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 SimpleScheduleBuilder  scheduleBuilder  =  SimpleScheduleBuilder.simpleSchedule();scheduleBuilder.withMisfireHandlingInstructionFireNow(); scheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); scheduleBuilder.withMisfireHandlingInstructionNextWithExistingCount(); scheduleBuilder.withMisfireHandlingInstructionNextWithRemainingCount(); scheduleBuilder.withMisfireHandlingInstructionNowWithExistingCount(); scheduleBuilder.withMisfireHandlingInstructionNowWithRemainingCount(); CronScheduleBuilder  cronScheduleBuilder  =  CronScheduleBuilder.cronSchedule("" );cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); 
错误 1 2 org.springframework.web.context.ContextLoader - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzJobServiceImpl': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzManager': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lxQuartzScheduler' defined in class path resource [spring/spring-quartz.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/transaction/UserTransaction 
是因为缺少jar包,添加如下依赖,即可
1 2 3 4 5 <dependency >     <groupId > javax.transaction</groupId >      <artifactId > jta</artifactId >      <version > 1.1</version >  </dependency >