Spring中使用quartz

jopen 9年前發布 | 47K 次閱讀 Quartz 作業調度框架

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</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!