MyException - 我的异常网
当前位置:我的异常网» 软件架构设计 » (转)Quartz 在 Spring 中怎么动态配置时间

(转)Quartz 在 Spring 中怎么动态配置时间

www.MyException.Cn  网友分享于:2013-07-02  浏览:51次
(转)Quartz 在 Spring 中如何动态配置时间
 在项目中有一个需求,需要灵活配置调度任务时间,并能自由启动或停止调度。 
有关调度的实现我就第一就想到了Quartz这个开源调度组件,因为很多项目使用过,Spring结合Quartz静态配置调度任务时间,非常easy。比如:每天凌晨几点定时运行一个程序,这只要在工程中的spring配置文件中配置好spring整合quartz的几个属性就好。 

Spring配置文件 
引用

<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
<property name="targetObject" ref="simpleService" /> 
<property name="targetMethod" value="test" /> 
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
<property name="jobDetail" ref="jobDetail" /> 
<property name="cronExpression" value="0 0/50 * ? * * *" /> 
</bean> 
<bean  id="schedulerTrigger" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
<property name="triggers"> 
<list>
<ref bean="cronTrigger"/>      
</list> 
</property> 
</bean> 


这种配置就是对quartz的一种简单的使用了,调度任务会在spring启动的时候加载到内存中,按照cronTrigger中定义的 cronExpression定义的时间按时触发调度任务。但是这是quartz使用“内存”方式的一种配置,也比较常见,当然对于不使用spring的项目,也可以单独整合quartz。方法也比较简单,可以从quartz的doc中找到配置方式,或者看一下《Quartz Job Scheduling Framework 》。 

但是对于想持久化调度任务的状态,并且灵活调整调度时间的方式来说,上面的内存方式就不能满足要求了,正如本文开始我遇到的情况,需要采用数据库方式集成 Quartz,这部分集成其实在《Quartz Job Scheduling Framework 》中也有较为详细的介绍,当然doc文档中也有,但是缺乏和spring集成的实例。 

一、需要构建Quartz数据库表,建表脚本在Quartz发行包的docs\dbTables目录,里面有各种数据库建表脚本,我采用的Quartz 1.6.5版本,总共12张表,不同版本,表个数可能不同。我用mysql数据库,执行了Quartz发行包的docs\dbTables\tables_mysql_innodb.sql建表。 

二、建立java project,完成后目录如下 
 

三、配置数据库连接池 
配置jdbc.properties文件 
引用

jdbc.driverClassName=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true 
jdbc.username=root 
jdbc.password=kfs 
cpool.checkoutTimeout=5000 
cpool.minPoolSize=10 
cpool.maxPoolSize=25 
cpool.maxIdleTime=7200 
cpool.acquireIncrement=5 
cpool.autoCommitOnClose=true 


配置applicationContext.xml文件 
引用

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:jee="http://www.springframework.org/schema/jee" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
     http://www.springframework.org/schema/jee 
       http://www.springframework.org/schema/jee/spring-jee-2.5.xsd"  > 
  
   <context:component-scan base-package="com.sundoctor"/> 

<!-- 属性文件读入 --> 
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
<property name="locations"> 
<list> 
<value>classpath:jdbc.properties</value> 
</list> 
</property> 
</bean> 

<!-- 数据源定义,使用c3p0 连接池 --> 
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialPoolSize" value="${cpool.minPoolSize}"/>
<property name="minPoolSize" value="${cpool.minPoolSize}" />
<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
<property name="acquireIncrement" value="${cpool.acquireIncrement}" /> 
    <property name="maxIdleTime" value="${cpool.maxIdleTime}"/>   
</bean>

</beans> 

这里只是配置了数据连接池,我使用c3p0 连接池,还没有涉及到Quartx有关配置,下面且听我慢慢道来。 

四、实现动态定时任务 
  什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。 
这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现 
引用

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" > 
         <property name="jobDetail" ref="schedulerJobDetail"/> 
         <property name="cronExpression"> 
             <value>0/10 * * * * ?</value> 
         </property> 

cronExpression是关键,如果可以动态设置cronExpression的值,就可以顺利解决问题了。这样我们就不能直接使用org.springframework.scheduling.quartz.CronTriggerBean,需要自己实现一个动态调度服务类,在其中构建CronTrigger或SimpleTrigger,动态配置时间。 
动态调度服务接口: 
Java代码  
  1. package com.sundoctor.quartz.service;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import org.quartz.CronExpression;  
  6.   
  7. public interface SchedulerService {  
  8.     /** 
  9.      * 根据 Quartz Cron Expression 调试任务 
  10.      * @param cronExpression  Quartz Cron 表达式,如 "0/10 * * ? * * *"等 
  11.      */  
  12.     void schedule(String cronExpression);  
  13.       
  14.     /** 
  15.      * 根据 Quartz Cron Expression 调试任务 
  16.      * @param name  Quartz CronTrigger名称 
  17.      * @param cronExpression Quartz Cron 表达式,如 "0/10 * * ? * * *"等 
  18.      */  
  19.     void schedule(String name,String cronExpression);  
  20.       
  21.     /** 
  22.      * 根据 Quartz Cron Expression 调试任务 
  23.      * @param cronExpression Quartz CronExpression 
  24.      */  
  25.     void schedule(CronExpression cronExpression);  
  26.       
  27.     /** 
  28.      * 根据 Quartz Cron Expression 调试任务 
  29.      * @param name Quartz CronTrigger名称 
  30.      * @param cronExpression Quartz CronExpression 
  31.      */  
  32.     void schedule(String name,CronExpression cronExpression);  
  33.       
  34.     /** 
  35.      * 在startTime时执行调试一次 
  36.      * @param startTime 调度开始时间 
  37.      */  
  38.     void schedule(Date startTime);    
  39.       
  40.     /** 
  41.      * 在startTime时执行调试一次 
  42.      * @param name Quartz SimpleTrigger 名称 
  43.      * @param startTime 调度开始时间 
  44.      */  
  45.     void schedule(String name,Date startTime);  
  46.       
  47.     /** 
  48.      * 在startTime时执行调试,endTime结束执行调度 
  49.      * @param startTime 调度开始时间 
  50.      * @param endTime 调度结束时间 
  51.      */  
  52.     void schedule(Date startTime,Date endTime);   
  53.       
  54.     /** 
  55.      * 在startTime时执行调试,endTime结束执行调度 
  56.      * @param name Quartz SimpleTrigger 名称 
  57.      * @param startTime 调度开始时间 
  58.      * @param endTime 调度结束时间 
  59.      */  
  60.     void schedule(String name,Date startTime,Date endTime);  
  61.       
  62.     /** 
  63.      * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次 
  64.      * @param startTime 调度开始时间 
  65.      * @param endTime 调度结束时间 
  66.      * @param repeatCount 重复执行次数 
  67.      */  
  68.     void schedule(Date startTime,Date endTime,int repeatCount);   
  69.       
  70.     /** 
  71.      * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次 
  72.      * @param name Quartz SimpleTrigger 名称 
  73.      * @param startTime 调度开始时间 
  74.      * @param endTime 调度结束时间 
  75.      * @param repeatCount 重复执行次数 
  76.      */  
  77.     void schedule(String name,Date startTime,Date endTime,int repeatCount);  
  78.       
  79.     /** 
  80.      * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次 
  81.      * @param startTime 调度开始时间 
  82.      * @param endTime 调度结束时间 
  83.      * @param repeatCount 重复执行次数 
  84.      * @param repeatInterval 执行时间隔间 
  85.      */  
  86.     void schedule(Date startTime,Date endTime,int repeatCount,long repeatInterval) ;  
  87.       
  88.     /** 
  89.      * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次 
  90.      * @param name Quartz SimpleTrigger 名称 
  91.      * @param startTime 调度开始时间 
  92.      * @param endTime 调度结束时间 
  93.      * @param repeatCount 重复执行次数 
  94.      * @param repeatInterval 执行时间隔间 
  95.      */  
  96.     void schedule(String name,Date startTime,Date endTime,int repeatCount,long repeatInterval);  
  97. }  


动态调度服务实现类: 
Java代码  
  1. package com.sundoctor.quartz.service;  
  2.   
  3. import java.text.ParseException;  
  4. import java.util.Date;  
  5. import java.util.UUID;  
  6.   
  7. import org.quartz.CronExpression;  
  8. import org.quartz.CronTrigger;  
  9. import org.quartz.JobDetail;  
  10. import org.quartz.Scheduler;  
  11. import org.quartz.SchedulerException;  
  12. import org.quartz.SimpleTrigger;  
  13. import org.springframework.beans.factory.annotation.Autowired;  
  14. import org.springframework.beans.factory.annotation.Qualifier;  
  15. import org.springframework.stereotype.Service;  
  16.   
  17. @Service("schedulerService")  
  18. public class SchedulerServiceImpl implements SchedulerService {  
  19.   
  20.     private Scheduler scheduler;  
  21.     private JobDetail jobDetail;  
  22.   
  23.     @Autowired  
  24.     public void setJobDetail(@Qualifier("jobDetail") JobDetail jobDetail) {  
  25.         this.jobDetail = jobDetail;  
  26.     }  
  27.   
  28.     @Autowired  
  29.     public void setScheduler(@Qualifier("quartzScheduler") Scheduler scheduler) {  
  30.         this.scheduler = scheduler;  
  31.     }  
  32.   
  33.     @Override  
  34.     public void schedule(String cronExpression) {  
  35.         schedule(null, cronExpression);  
  36.     }  
  37.   
  38.     @Override  
  39.     public void schedule(String name, String cronExpression) {  
  40.         try {  
  41.             schedule(name, new CronExpression(cronExpression));  
  42.         } catch (ParseException e) {  
  43.             throw new RuntimeException(e);  
  44.         }  
  45.     }  
  46.   
  47.     @Override  
  48.     public void schedule(CronExpression cronExpression) {  
  49.         schedule(null, cronExpression);  
  50.     }  
  51.   
  52.     @Override  
  53.     public void schedule(String name, CronExpression cronExpression) {  
  54.         if (name == null || name.trim().equals("")) {  
  55.             name = UUID.randomUUID().toString();  
  56.         }  
  57.   
  58.         try {  
  59.             scheduler.addJob(jobDetail, true);  
  60.   
  61.             CronTrigger cronTrigger = new CronTrigger(name, Scheduler.DEFAULT_GROUP, jobDetail.getName(),  
  62.                     Scheduler.DEFAULT_GROUP);  
  63.             cronTrigger.setCronExpression(cronExpression);  
  64.             scheduler.scheduleJob(cronTrigger);  
  65.             scheduler.rescheduleJob(name, Scheduler.DEFAULT_GROUP, cronTrigger);  
  66.         } catch (SchedulerException e) {  
  67.             throw new RuntimeException(e);  
  68.         }  
  69.     }  
  70.   
  71.     @Override  
  72.     public void schedule(Date startTime) {  
  73.         schedule(startTime, null);  
  74.     }  
  75.   
  76.     @Override  
  77.     public void schedule(String name, Date startTime) {  
  78.         schedule(name, startTime, null);  
  79.     }  
  80.   
  81.     @Override  
  82.     public void schedule(Date startTime, Date endTime) {  
  83.         schedule(startTime, endTime, 0);  
  84.     }  
  85.   
  86.     @Override  
  87.     public void schedule(String name, Date startTime, Date endTime) {  
  88.         schedule(name, startTime, endTime, 0);  
  89.     }  
  90.   
  91.     @Override  
  92.     public void schedule(Date startTime, Date endTime, int repeatCount) {  
  93.         schedule(null, startTime, endTime, 0);  
  94.     }  
  95.   
  96.     @Override  
  97.     public void schedule(String name, Date startTime, Date endTime, int repeatCount) {  
  98.         schedule(name, startTime, endTime, 0, 0L);  
  99.     }  
  100.   
  101.     @Override  
  102.     public void schedule(Date startTime, Date endTime, int repeatCount, long repeatInterval) {  
  103.         schedule(null, startTime, endTime, repeatCount, repeatInterval);  
  104.     }  
  105.   
  106.     @Override  
  107.     public void schedule(String name, Date startTime, Date endTime, int repeatCount, long repeatInterval) {  
  108.         if (name == null || name.trim().equals("")) {  
  109.             name = UUID.randomUUID().toString();  
  110.         }  
  111.   
  112.         try {  
  113.             scheduler.addJob(jobDetail, true);  
  114.   
  115.             SimpleTrigger SimpleTrigger = new SimpleTrigger(name, Scheduler.DEFAULT_GROUP, jobDetail.getName(),  
  116.                     Scheduler.DEFAULT_GROUP, startTime, endTime, repeatCount, repeatInterval);  
  117.             scheduler.scheduleJob(SimpleTrigger);  
  118.             scheduler.rescheduleJob(name, Scheduler.DEFAULT_GROUP, SimpleTrigger);  
  119.   
  120.         } catch (SchedulerException e) {  
  121.             throw new RuntimeException(e);  
  122.         }  
  123.     }  
  124. }  

SchedulerService 只有一个多态方法schedule,SchedulerServiceImpl实现SchedulerService接口,注入org.quartz.Schedulert和org.quartz.JobDetail,schedule方法可以动态配置org.quartz.CronExpression或org.quartz.SimpleTrigger调度时间。 

五、实现自己的org.quartz.JobDetail 
在上一步中SchedulerServiceImpl需要注入org.quartz.JobDetail,在以前的静态配置中 
引用

<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
<property name="targetObject" ref="simpleService" /> 
<property name="targetMethod" value="testMethod" /> 
</bean>

中使用org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean。在这里使用org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean。会报 
引用


Caused by: java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'methodInvoker' is not serializable: org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean 
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.serializeJobData(StdJDBCDelegate.java:3358) 
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.insertJobDetail(StdJDBCDelegate.java:515) 
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1102) 
... 11 more 


异常,google了一下,没有找到解决方法。所以在这里不能使用org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean。,不能pojo了,需要使用org.springframework.scheduling.quartz.JobDetailBean和org.springframework.scheduling.quartz.QuartzJobBean实现自己的QuartzJobBean,如下: 
Java代码  
  1. package com.sundoctor.example.service;  
  2.   
  3. import org.quartz.JobExecutionContext;  
  4. import org.quartz.JobExecutionException;  
  5. import org.quartz.Trigger;  
  6. import org.springframework.scheduling.quartz.QuartzJobBean;  
  7.   
  8. public class MyQuartzJobBean extends QuartzJobBean {  
  9.   
  10.     private SimpleService simpleService;  
  11.       
  12.     public void setSimpleService(SimpleService simpleService) {  
  13.         this.simpleService = simpleService;  
  14.     }  
  15.   
  16.     @Override  
  17.     protected void executeInternal(JobExecutionContext jobexecutioncontext) throws JobExecutionException {  
  18.         Trigger trigger = jobexecutioncontext.getTrigger();  
  19.         String triggerName = trigger.getName();       
  20.         simpleService.testMethod(triggerName);  
  21.     }  
  22.   
  23. }  


MyQuartzJobBean继承org.springframework.scheduling.quartz.QuartzJobBean,注入的SimpleService如下: 
Java代码  收藏代码
  1. package com.sundoctor.example.service;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import org.slf4j.Logger;  
  6. import org.slf4j.LoggerFactory;  
  7. import org.springframework.stereotype.Service;  
  8.   
  9. @Service("simpleService")  
  10. public class SimpleService implements Serializable{  
  11.       
  12.     private static final long serialVersionUID = 122323233244334343L;  
  13.     private static final Logger logger = LoggerFactory.getLogger(SimpleService.class);  
  14.       
  15.     public void testMethod(String triggerName){  
  16.         //这里执行定时调度业务  
  17.         logger.info(triggerName);  
  18.     }  
  19.       
  20.     public void testMethod2(){  
  21.         logger.info("testMethod2");  
  22.     }  
  23. }  

SimpleService主要执行定时调度业务,在这里我只是简单打印一下log日志。SimpleService需要实现java.io.Serializable接口,否则会报 
引用
Caused by: java.io.InvalidClassException: com.sundoctor.example.service.SimpleService; class invalid for deserialization 
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:587) 
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583) 
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732) 
... 64 more

异常。 

配置applicationContext-quartz.xml文件: 
引用

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> 

<beans> 
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
<property name="dataSource">  
<ref bean="dataSource" />  
</property> 
<property name="applicationContextSchedulerContextKey"  value="applicationContextKey" /> 
<property name="configLocation" value="classpath:quartz.properties"/> 
</bean> 

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> 
<property name="jobClass"> 
<value>com.sundoctor.example.service.MyQuartzJobBean</value> 
</property> 

<property name="jobDataAsMap"> 
<map> 
<entry key="simpleService"> 
<ref bean="simpleService" /> 
</entry> 
</map> 
</property> 

</bean>
</beans> 


quartzScheduler中没有了 
引用

<property name="triggers"> 
<list> 
...      
</list> 
/property> 

配置,通过SchedulerService动态加入CronTrigger或SimpleTrigger。 

在红色的 
引用


<property name="jobDataAsMap"> 
<map> 
<entry key="simpleService"> 
<ref bean="simpleService" /> 
</entry> 
</map> 
</property> 


中需要注入调度业务类,否则会报空指指错误。 

dataSource:项目中用到的数据源,里面包含了quartz用到的12张数据库表; 
applicationContextSchedulerContextKey: 是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类中把spring上下文以key/value的方式存放在了quartz的上下文中了,可以用applicationContextSchedulerContextKey所定义的key得到对应的spring上下文; 
configLocation:用于指明quartz的配置文件的位置,如果不用spring配置quartz的话,本身quartz是通过一个配置文件进行配置的,默认名称是quartz.properties,里面配置的参数在quartz的doc文档中都有介绍,可以调整quartz,我在项目中也用这个文件部分的配置了一些属性,代码如下: 
引用

org.quartz.scheduler.instanceName = DefaultQuartzScheduler 
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.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true 

org.quartz.jobStore.misfireThreshold = 60000 

#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore 

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX 
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate 
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate 
#org.quartz.jobStore.useProperties = true 
org.quartz.jobStore.tablePrefix = QRTZ_  
org.quartz.jobStore.isClustered = false  
org.quartz.jobStore.maxMisfiresToHandleAtATime=1 

这里面没有数据源相关的配置部分,采用spring注入datasource的方式已经进行了配置。 

六、测试 
运行如下测试类 
Java代码  收藏代码
  1. package com.sundoctor.example.test;  
  2.   
  3. import java.text.ParseException;  
  4. import java.text.SimpleDateFormat;  
  5. import java.util.Date;  
  6.   
  7. import org.springframework.context.ApplicationContext;  
  8. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  9.   
  10. import com.sundoctor.quartz.service.SchedulerService;  
  11.   
  12. public class MainTest {  
  13.   
  14.     /** 
  15.      * @param args 
  16.      */  
  17.     public static void main(String[] args) {  
  18.         ApplicationContext springContext = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext.xml","classpath:applicationContext-quartz.xml"});  
  19.         SchedulerService schedulerService = (SchedulerService)springContext.getBean("schedulerService");  
  20.           
  21.         //执行业务逻辑...  
  22.           
  23.         //设置调度任务  
  24.         //每10秒中执行调试一次  
  25.         schedulerService.schedule("0/10 * * ? * * *");   
  26.           
  27.         Date startTime = parse("2009-06-01 22:16:00");  
  28.         Date endTime =  parse("2009-06-01 22:20:00");  
  29.           
  30.         //2009-06-01 21:50:00开始执行调度  
  31.         schedulerService.schedule(startTime);  
  32.   
  33.         //2009-06-01 21:50:00开始执行调度,2009-06-01 21:55:00结束执行调试  
  34.         //schedulerService.schedule(startTime,endTime);  
  35.           
  36.         //2009-06-01 21:50:00开始执行调度,执行5次结束  
  37.         //schedulerService.schedule(startTime,null,5);  
  38.   
  39.         //2009-06-01 21:50:00开始执行调度,每隔20秒执行一次,执行5次结束  
  40.         //schedulerService.schedule(startTime,null,5,20);  
  41.           
  42.         //等等,查看com.sundoctor.quartz.service.SchedulerService          
  43.     }  
  44.       
  45.     private static Date parse(String dateStr){  
  46.         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  47.         try {  
  48.             return format.parse(dateStr);  
  49.         } catch (ParseException e) {  
  50.             throw new RuntimeException(e);  
  51.         }  
  52.     }  
  53.   
  54. }  

输出 
引用

[2009-06-02 00:08:50]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 
[2009-06-02 00:10:20]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 
[2009-06-02 00:10:30]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 
[2009-06-02 00:10:40]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 
[2009-06-02 00:10:50]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 
[2009-06-02 00:11:00]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 
[2009-06-02 00:11:10]INFO  com.sundoctor.example.service.SimpleService(line:17) -2059c26f-9462-49fe-b4ce-be7e7a29459f 


这样只是简单的将quartz trigger名称打印出来。 

这样通过SchedulerService就可以动态配置调度时间。其实SchedulerService 还可扩展,比如可以注入多个JobDetail,调度不同的JobDetail。 

文章评论

程序员都该阅读的书
程序员都该阅读的书
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
程序员和编码员之间的区别
程序员和编码员之间的区别
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
我的丈夫是个程序员
我的丈夫是个程序员
 程序员的样子
程序员的样子
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
Java程序员必看电影
Java程序员必看电影
一个程序员的时间管理
一个程序员的时间管理
老程序员的下场
老程序员的下场
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
10个调试和排错的小建议
10个调试和排错的小建议
程序员必看的十大电影
程序员必看的十大电影
我是如何打败拖延症的
我是如何打败拖延症的
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
总结2014中国互联网十大段子
总结2014中国互联网十大段子
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
编程语言是女人
编程语言是女人
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员应该关注的一些事儿
程序员应该关注的一些事儿
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
漫画:程序员的工作
漫画:程序员的工作
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
为什么程序员都是夜猫子
为什么程序员都是夜猫子
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
中美印日四国程序员比较
中美印日四国程序员比较
代码女神横空出世
代码女神横空出世
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
那些争议最大的编程观点
那些争议最大的编程观点
程序员的鄙视链
程序员的鄙视链
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
每天工作4小时的程序员
每天工作4小时的程序员
如何成为一名黑客
如何成为一名黑客
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有