基于Spring实现定时调度

来源:互联网 发布:工商银行的软件下载 编辑:程序博客网 时间:2024/05/18 16:38
比较常用的是,Spring对Quartz的支持,可以非常容易地进行定时任务的调度。一般,具有两种方式实现定时调度:一种是通过继承Spring的org.springframework.scheduling.quartz.QuartzJobBean来定义定时任务,这种情况下与Spring代码有一定耦合。下面,通过例子来说明:实现一个定时任务类,代码如下所示:    package org.shirdrn.spring.scheduler.quartz;            import org.apache.log4j.Logger;      import org.quartz.JobExecutionContext;      import org.quartz.JobExecutionException;      import org.springframework.scheduling.quartz.QuartzJobBean;            public class MyQuartzJob extends QuartzJobBean {                private static final Logger LOG = Logger.getLogger(MyQuartzJob.class);          private static int counter = 0;                @Override          protected void executeInternal(JobExecutionContext context)                  throws JobExecutionException {              JobControlInfo job = (JobControlInfo) context.getMergedJobDataMap().get("jobControlInfo");              String manager = (String) context.getMergedJobDataMap().get("manager");              int length = Integer.parseInt((String) context.getMergedJobDataMap().get("length"));              LOG.info("context: job=" + job + ", manager=" + manager + ", length=" + length);              LOG.info("Execute quartz job /"" + (++counter) + "/".");          }      }  上面的JobExecutionContext context是一个任务执行上下文,可以通过配置,将需要的数据传递给executeInternal方法,然后在该方法中定义任务的处理逻辑。这里,假设有一个类包含了对定时任务的控制信息,实现类为JobControlInfo,形式化定义如下所示:    package org.shirdrn.spring.scheduler.quartz;            public class JobControlInfo {            }  通过Spring配置传递给JobExecutionContext context。Spring配置文件quartz.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:p="http://www.springframework.org/schema/p"          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">                    <bean id="myScheduler" lazy-init="false" autowire="no"              class="org.springframework.scheduling.quartz.SchedulerFactoryBean">              <property name="triggers">                  <list>                      <ref bean="myQuartzJobTrigger" />                  </list>              </property>          </bean>          <bean id="myQuartzJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">              <property name="jobDetail" ref="myQuartzJobDetail" />              <property name="startDelay" value="5000"/>              <property name="repeatInterval" value="2000" />          </bean>          <bean id="myQuartzJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">              <property name="jobClass">                  <value>org.shirdrn.spring.scheduler.quartz.MyQuartzJob</value>              </property>              <property name="jobDataAsMap">                  <map>                      <entry key="jobControlInfo" value-ref="jobControlInfo" />                      <entry key="length" value="100000" />                      <entry key="manager" value="Jack" />                  </map>              </property>          </bean>          <bean id="jobControlInfo" class="org.shirdrn.spring.scheduler.quartz.JobControlInfo" scope="prototype"/>            </beans>  下面可以启动定时任务了,代码如下所示:    package org.shirdrn.spring.scheduler.quartz;            import java.io.BufferedReader;      import java.io.IOException;      import java.io.InputStreamReader;            import org.quartz.impl.StdScheduler;      import org.springframework.context.ApplicationContext;      import org.springframework.context.support.ClassPathXmlApplicationContext;            public class ContextInitializer {          public static void main(String[] args) {              ApplicationContext ctx = new ClassPathXmlApplicationContext(                      "org/shirdrn/spring/scheduler/quartz/quartz.xml");              StdScheduler myScheduler = (StdScheduler)ctx.getBean("myScheduler");              BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));              try {                  while(true) {                      String line = reader.readLine();                      if(line!=null) {                          boolean quit = line.trim().equalsIgnoreCase("quit") || line.trim().equalsIgnoreCase("q");                          if(quit) {                              myScheduler.shutdown(true);                              break;                          }                      }                  }              } catch (IOException e) {                  e.printStackTrace();              }          }      }  我们定义这个定时任务,执行时间间隔为2s。 另一种是完全与Spring代码解耦合,而只是通过Spring配置就能进行定时任务的配置,一个定时任务可以是任意的Java处理类。而对于定时的配置,是基于Unix系统的crontab命令来实现的,更加灵活地配置定时任务。下面说明实现方法:定义一个普通的Java类,里面的一个方法里面包含了定时任务的处理逻辑,如下所示:    package org.shirdrn.spring.scheduler.quartz.cron;            import org.apache.log4j.Logger;                  public class MyQuartzJob {                private static final Logger LOG = Logger.getLogger(MyQuartzJob.class);          private static int counter = 0;                    public void scan() {              LOG.info("Execute quartz job /"" + (++counter) + "/".");          }      } 然后看下Spring配置文件quartz.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:p="http://www.springframework.org/schema/p"          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">                <bean id="myScheduler" lazy-init="false" autowire="no"              class="org.springframework.scheduling.quartz.SchedulerFactoryBean">              <property name="triggers">                  <list>                      <ref bean="myJobTrigger" />                  </list>              </property>          </bean>          <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">              <property name="jobDetail">                  <ref bean="myJobDetail" />              </property>              <property name="cronExpression">                  <value>00,10,20,30,40,50 * * * * ?</value>              </property>          </bean>          <bean id="myJobDetail"              class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">              <property name="targetObject">                  <ref bean="myJob" />              </property>              <property name="targetMethod">                  <value>scan</value>              </property>          </bean>          <bean id="myJob" class="org.shirdrn.spring.scheduler.quartz.cron.MyQuartzJob" />      </beans>  通过Spring的org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean来设置目标定时任务处理内容,如处理类和处理方法,通过org.springframework.scheduling.quartz.CronTriggerBean的cronExpression属性来配置定时任务,非常灵活。上述配置,定时任务会自动调用MyQuartzJob类的scan方法来执行任务。对于cronExpression属性的值,包括以下7 个字段:    秒       分       小时       月内日期       月       周内日期       年(可选字段)  有关各个字段可以设置的值:    Cron 触发器利用一系列特殊字符,如下所示:            ?反斜线(/)字符表示增量值。例如,在秒字段中“5/15”代表从第 5 秒开始,每 15 秒一次。                  ?问号(?)字符和字母 L 字符只有在月内日期和周内日期字段中可用。问号表示这个字段不包含具体值。所以,如果指定月内日期,可以在周内日期字段中插入“?”,表示周内日期值无关紧要。字母 L 字符是 last 的缩写。放在月内日期字段中,表示安排在当月最后一天执行。在周内日期字段中,如果“L”单独存在,就等于“7”,否则代表当月内周内日期的最后一个实例。所以“0L”表示安排在当月的最后一个星期日执行。                  ?在月内日期字段中的字母(W)字符把执行安排在最靠近指定值的工作日。把“1W”放在月内日期字段中,表示把执行安排在当月的第一个工作日内。                  ?井号(#)字符为给定月份指定具体的工作日实例。把“MON#2”放在周内日期字段中,表示把任务安排在当月的第二个星期一。                  ?星号(*)字符是通配字符,表示该字段可以接受任何可能的值。    更多信息可以查阅相关资料。启动定时任务,测试代码如下所示:    package org.shirdrn.spring.scheduler.quartz.cron;            import org.springframework.context.ApplicationContext;      import org.springframework.context.support.ClassPathXmlApplicationContext;            public class ContextInitializer {          public static void main(String[] args) {              ApplicationContext ctx = new ClassPathXmlApplicationContext(                      "org/shirdrn/spring/scheduler/quartz/cron/quartz.xml");              ctx.getBean("myScheduler");          }      }  

 
原创粉丝点击