1. 程式人生 > >Quartz2.x學習筆記(三):Quartz2.x整合spring

Quartz2.x學習筆記(三):Quartz2.x整合spring

spring是個很優秀的框架,它提供了對Quartz的支援。但spring3.1以下的版本不支援Quartz2.x,支援1.x的版本。 下面就簡單說說spring整合quartz方法。 我使用的是maven工程。 我匯入的依賴的jar包如下:
  <properties>
    <!-- spring版本號 -->
    <spring.version>3.2.4.RELEASE</spring.version>
    <!-- mybatis版本號 -->
    <mybatis.version>3.2.8</mybatis.version>
    <!-- log4j日誌檔案管理包版本 -->
    <slf4j.version>1.7.7</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <!-- 表示開發的時候引入,釋出的時候不會載入此包 -->
      <scope>test</scope>
    </dependency>
    <!-- spring核心包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- 日誌檔案管理包 -->
    <!-- log start -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
     <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
     <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
    </dependency>
    <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
     </dependency>
     <!-- 匯入Mysql資料庫連線jar包 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.30</version>
    </dependency>

jdk版本使用的是1.7 RAMJobStore: 接下來建立一個spring的配置檔案。 主要步驟如下:   1:定義工作任務的Job   2:定義觸發器Trigger,並將觸發器與工作任務繫結   3:定義排程器,並將Trigger註冊到Scheduler applicationContext.xml
<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:p="http://www.springframework.org/schema/p"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<!-- 1:定義任務的bean ,這裡使用JobDetailFactoryBean,也可以使用MethodInvokingJobDetailFactoryBean ,配置類似-->
    <bean name="hwJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
       <!--  指定job的名稱 -->
        <property name="name" value="hw_job"/>
        <!-- 指定job的分組 -->
        <property name="group" value="hw_group"/>
        <!-- 指定具體的job類 -->
        <property name="jobClass" value="web_statistics.HelloWorldJob"/>
        <!-- 必須設定為true,如果為false,當沒有活動的觸發器與之關聯時會在排程器中會刪除該任務  -->
        <property name="durability" value="true"/>
        <!-- 指定spring容器的key,如果不設定在job中的jobmap中是獲取不到spring容器的 -->
        <property name="applicationContextJobDataKey" value="applicationContext"/>
    </bean>
    <!-- 2.1:定義觸發器的bean,定義一個Simple的Trigger,一個觸發器只能和一個任務進行繫結 -->
  <!-- <bean name="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
  指定Trigger的名稱
  <property name="name" value="hw_trigger"/>
  指定Trigger的名稱
  <property name="group" value="hw_trigger_group"/>
  指定Tirgger繫結的Job
  <property name="jobDetail" ref="hwJob"/>
  指定Trigger的延遲時間 1s後執行
  <property name="startDelay" value="1000"/>
  指定Trigger的重複間隔 5s
  <property name="repeatInterval" value="5000"/>
  指定Trigger的重複次數
  <property name="repeatCount" value="5"/>
  </bean> -->

   <!-- 2.2:定義觸發器的bean,定義一個Cron的Trigger,一個觸發器只能和一個任務進行繫結 -->
   <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
   <!-- 指定Trigger的名稱 -->
   <property name="name" value="hw_trigger"/>
   <!-- 指定Trigger的名稱 -->
   <property name="group" value="hw_trigger_group"/>
   <!-- 指定Tirgger繫結的Job -->
   <property name="jobDetail" ref="hwJob"/>
   <!-- 指定Cron 的表示式 ,當前是每隔3s執行一次 -->
    <property name="cronExpression" value="0/3 * * * * ?" />
   </bean>

    <!-- 3.定義排程器,並將Trigger註冊到排程器中 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
              <--  <ref bean="simpleTrigger"/>-->
                <ref bean="cronTrigger"/>
            </list>
        </property>
        <property name="autoStartup" value="true" />
    </bean>
</beans>
classpath下放置log4j配置檔案,用於輸出日誌資訊(log4j.properties):
### 設定###
log4j.rootLogger = info,stdout

### 輸出資訊到控制檯 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
建立配置檔案裡所指的類:
import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 測試job
 * @author Howard
 * 2017年2月23日
 */
public class HelloWorldJob implements Job{
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info("作業執行 !"+context.getJobDetail().getKey());
        log.info("時間!"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) );
        log.info(" \n \n");
    }

}
注意包名與配置檔案的對應 如果你是一個web應用 建立web.xml並配置spring,然後部署該專案,啟動就可以看到控制檯每隔3秒列印的job資訊了。 如果你的不是一個web專案,那還需要建立一個類用於測試!
public class Test {

    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

    }
}
右鍵run執行即可可到控制檯輸出資訊如下:
(注意這裡我使用的是cronTrigger 的配置 相應的在配置檔案裡要註釋掉關於simpletrigger的部分)

可以看到每隔3秒執行一次作業 jdbcjobstore: 上面介紹的是job排程資訊儲存在rom的方法,但實際應用中經常將job的資訊儲存到資料庫裡。下面說下jdbc的配置方法。 改下applicationContext.xml:
<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:p="http://www.springframework.org/schema/p"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.2.xsd">

   <bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
        <property name="configLocation" value="classpath:quartz.properties"/>
    </bean>
</beans>
上面的配置指向了classpath下的quartz.properties檔案,所以還需要增加quartz.properties檔案。
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

#叢集配置
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
#Quartz預設配置 儲存到記憶體
#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.StdJDBCDelegate
org.quartz.jobStore.useProperties:true
#資料庫表字首
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS

#============================================================================
# Configure Datasources
#============================================================================
JDBC驅動

org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartztest
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:10
完成後,建立測試類如下:
package web_statistics;

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdScheduler;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * 測試Quartz jdbc配置方式整合Quartz
 * @author Howard
 * 2017年2月23日
 */
public class Test2 {

     private static Scheduler scheduler;

     public static void main(String[] args) throws SchedulerException, InterruptedException {

           ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
           //通過spring的方式獲取bean
        scheduler = (StdScheduler)ac.getBean("scheduler");
           // 1、建立一個JobDetail例項,指定Quartz
        JobDetail jobDetail = JobBuilder.newJob(HelloWorldJob.class) // 任務執行類
                .withIdentity("job_1", "group_1")// 任務名,任務組
                .build();

        // 觸發器型別
//        SimpleScheduleBuilder builder = SimpleScheduleBuilder
//                .repeatSecondlyForTotalCount(5, 3); //  設定執行次數

        //CronSchedule 每3秒執行一次
        CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?");
        // 2、建立Trigger
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger_1", "group_1").startNow()
                .withSchedule(builder)
                .build();

        // 3、建立Scheduler
        scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.scheduleJob(jobDetail, trigger);
        // 4、排程執行
        scheduler.start();
     }
}
執行後如下:

相應的可以在資料庫裡看到作業排程的資訊。