Spring中使用quartz

jopen 10年前

1.Quartz基础

     quartz对任务调度核心领域问题惊醒了高度抽象,提出了调度器,任务,和触发器这三个核心概念,并在org.quartz通过接口和类对核心概念进行描述。

Scheduler接口: quartz的执行线程,它根据Trigger决定调度时刻,根据JobDetail的说明实例化并运行Job

JobDetail类: 可持久化的任务描述信息。任务虽然分组,但是仅用作管理标示,任务之间并无实质性关联, 例如无法定义job chain。

Trigger类:任务的调度策略。这里的特点是调度策略与任务描述分开,调度策略和任务描述都可以分别在Scheduler注册,然后再关联起来。JobDetail与Trigger的关系是一对多。

JobDataMap: 将任务的运行时可持久化状态信息从JobDetail类中分离出来

Job接口: 任务的执行代码

StatefulJob接口: 无状态任务对应的JobDataMap可以认为是只读的,而有状态的任务在多次执行过程中保留对JobDataMap所作的修改,一个后果是有状态任务无法被并发执行。

JobExecutionException类: 可以通过JobExecutionException调整调度程序的下一步动作

Calendar接口: 用于从trigger的调度计划中排除某些时间段,例如假期等。

 ThreadPool:

2.使用SimpleTrigger与CronTrigger:

import org.quartz.*;  import org.quartz.impl.StdSchedulerFactory;  /**   * Created by Dou on 2014/12/1 0001.   */  public class SimpleTriggerAndCornTriggerRunner {      public static void main(String[] args) {          try {              /**               * quartz jar 2.2.1版本写法               */              //创建jobDeail实例,绑定Job实现类              //指明job的名称,组名,以及绑定的类 jar包版本为2.2.1              JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class).withIdentity("job1_2", "jGroup1").build();              //使用simpleTrigger规则  jar包版本为2.2.1              Trigger simpleTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1_1","tgroup1").startNow()                      .withSchedule(SimpleScheduleBuilder.simpleSchedule()                              .withIntervalInSeconds(2) //时间价格                              .withRepeatCount(4)       //重复次数(将执行5次)                      )                      .build();              //使用CornTrigger规则  jar包版本为2.2.1              Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1_2","tgroup1")                      .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))                      .startNow()                      .build();              /**               * quartz jar 1.8.4版本写法               */  //            JobDetail jobDetail = new JobDetail("job1_1", "jgroup1",SimpleJob.class);  //              //使用CornTrigger规则 1.8.4版本写法  //            SimpleTrigger simpleTrigger = new SimpleTrigger("trigger1_1","tgroup1");  //            simpleTrigger.setStartTime(new Date());  //              simpleTrigger.setRepeatInterval(2000);  //              simpleTrigger.setRepeatCount(100);                //使用CornTrigger规则 1.8.4版本写法  /*            CronTrigger cronTrigger = new CronTrigger("trigger1_2", "tgroup1");                CronExpression cexp = new CronExpression("0/5 * * * * ?");                cronTrigger.setCronExpression(cexp);*/              /**               * quartz jar 1.8.4版本写法end               */                        SchedulerFactory schedulerFactory =new StdSchedulerFactory();              Scheduler scheduler = null;              //通过schedulerFActory获得一个调度器              scheduler = schedulerFactory.getScheduler();              //把作业和触发器注册到任务调度中              scheduler.scheduleJob(jobDetail,simpleTrigger);              //启动调度              scheduler.start();              //1.8.4版本 使用corntrigger方式看本例的时候需要通过(Thread.currentThread().sleep();)方式让主线程睡眠一段时间,              //使用调度器可以继续执行任务调度的工作。否则在调度器启动后,因为主线程马上推出去,              //寄生于主线程的调度器也将关闭,调度器中的任务都将相应销毁,导致看不清实际的运行效              //果。              //可以通过单元测试的时候让主线程睡眠一段时间,使用下面的方式。              //  /*            try {                  // wait 30 seconds to show jobs                  Thread.sleep(30L * 1000L);                  // executing...              } catch (Exception e) {              }              scheduler.shutdown(true);*/          }catch (Exception e){          }      }  }


所需job类:

import org.quartz.Job;  import org.quartz.JobExecutionContext;  import org.quartz.JobExecutionException;  import java.text.SimpleDateFormat;  import java.util.Date;  /**   * Created by Dou on 2014/11/28 0028.   */  /*  <!-- 如果在spring中使用MethodInvokingJobDetailFactoryBean 业务类注册job时候不用实现job接口 在spring3.x.x版本后可用 -->   */  public class SimpleJob implements Job {      @Override      public void execute(JobExecutionContext jobEC) throws JobExecutionException {          System.out.println(" Time is: "+( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));      }      public void doWork(){          System.out.println(" Time is: "+( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));      }  }  public class MyService { 不实现Job接口的job      public void test(){          System.out.println("Hello!");      }  }

quart与spring:

web.xml:   <context-param>     <param-name>contextConfigLocation</param-name>     <param-value>           classpath*:/applicationContext-main.xml,classpath*:/applicationContext-quartz.xml         </param-value>  </context-param>  applicationContext-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-4.0.xsd"         default-lazy-init="true">      <!-- 启动触发器 -->      <bean name="scheduler" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">          <property name="triggers">              <list>                  <ref bean="myJobTrigger" />                  <ref bean="simpleTrigger" />              </list>          </property>          <property name="startupDelay" value="30" />  <!--单位:秒-->          <property name="configLocation" value="classpath:/quartz.properties" />      </bean>      <!-- 调度配置 -->      <!-- 调度配置cronTrigger -->      <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"           p:startDelay="1000" >  <!--单位:毫秒-->          <property name="jobDataAsMap">              <map>                  <entry key="count" value="10" />              </map>          </property>          <property name="jobDetail">              <ref bean="myJobDetail" />          </property>          <property name="cronExpression">              <value>0/3 * * * * ?</value>          </property>      </bean>      <!-- 调度配置simpleTrigger -->      <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"            p:jobDetail-ref="myJobDetail" p:startDelay="1000" p:repeatInterval="2000"            p:repeatCount="100">          <property name="jobDataAsMap">              <map>                  <entry key="count" value="10" />              </map>          </property>      </bean>            <!-- job配置 -->      <!-- 使用MethodInvokingJobDetailFactoryBean 业务类不用实现job接口 在spring3.x.x版本后可用 -->      <bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">          <property name="targetObject">              <ref bean="myService" />          </property>          <property name="targetMethod">              <value>test</value>          </property>          <property name="concurrent">  <!-- 指定任务类型是否与状态 false:有状态,有状态的任务不能并发执行-->              <value>false</value>          </property>      </bean>      <bean id="myJob" class="com.dou.app.quartz.SimpleJob"/>      <bean id="myService" class="com.dou.app.quartz.MyService"/>  <!-- quartz.jar.1.x 版本写法 -->      <!--<bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"-->            <!--p:jobClass="com.dou.app.quartz.SimpleJob"-->            <!--p:applicationContextJobDataKey="applicationContext">-->          <!--<property name="jobDataAsMap">-->              <!--<map>-->                  <!--<entry key="size" value="10" />-->              <!--</map>-->          <!--</property>-->      <!--</bean>-->      <!--<bean id="scheduler"-->            <!--class="org.springframework.scheduling.quartz.SchedulerFactoryBean">-->          <!--<property name="triggers">-->              <!--<list>-->                  <!--<ref bean="simpleTrigger" />-->              <!--</list>-->          <!--</property>-->          <!--<property name="schedulerContextAsMap">-->              <!--<map>-->                  <!--<entry key="timeout" value="30" />-->              <!--</map>-->          <!--</property>-->          <!--<property name="quartzProperties">-->              <!--<props>-->                  <!--<prop key="org.quartz.threadPool.class">-->                      <!--org.quartz.simpl.SimpleThreadPool-->                  <!--</prop>-->                  <!--<prop key="org.quartz.threadPool.threadCount">10</prop>-->              <!--</props>-->          <!--</property>-->      <!--</bean>-->  </beans>

quartz.properties:

#集群的配置,这里不使用集群  #org.quartz.scheduler.instanceName = DefaultQuartzScheduler  #配置调度器的线程池  org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool  org.quartz.threadPool.threadCount = 10  org.quartz.threadPool.threadPriority = 5  org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true  # Using RAMJobStore  ## if using RAMJobStore, please be sure that you comment out the following  ## - org.quartz.jobStore.tablePrefix,   ## - org.quartz.jobStore.driverDelegateClass,   ## - org.quartz.jobStore.dataSource  #配置任务调度现场数据保存机制  # RAMJobStore:将信息保存在RAM中  org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore  # Using JobStoreTX 将调度现场数据保存在数据库中  ## Be sure to run the appropriate script(under docs/dbTables) first to create tables  #org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX  # Configuring JDBCJobStore with the Table Prefix 设定数据库表前缀  #org.quartz.jobStore.tablePrefix = QRTZ_  # Using DriverDelegate  #org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate  #org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate  #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate  # Using datasource 设置数据源名称  #org.quartz.jobStore.dataSource = qzDS  # Define the datasource to use  ##Mysql  #org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver  #org.quartz.dataSource.qzDS.URL = jdbc:mysql://192.168.3.128:3306/manager?useUnicode=true&characterEncoding=utf-8  #org.quartz.dataSource.qzDS.user = root  #org.quartz.dataSource.qzDS.password = 1234  #org.quartz.dataSource.qzDS.maxConnections = 30  #Oracle  #org.quartz.dataSource.qzDS.driver = oracle.jdbc.driver.OracleDriver  #org.quartz.dataSource.qzDS.URL = jdbc:oracle:thin:@localhost:1521:ora9i  #org.quartz.dataSource.qzDS.user = stamen  #org.quartz.dataSource.qzDS.password = abc  #org.quartz.dataSource.qzDS.maxConnections = 30