1. 程式人生 > >Spring集成Quartz的3種方式

Spring集成Quartz的3種方式

else rda set str class tailf tco 調度 quest

1.使用xml配置方式

Maven依賴

    <properties>
        <!-- spring版本號 -->
        <spring.version>4.2.2.RELEASE</spring.version>                      <!-- Quartz的版本 -->
    </properties>
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</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-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.2</version>
        </dependency>

application.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 配置Job類 -->
    <bean id="myJob" class="cn.enjoyedu.quartz.xml.CronJob"></bean>

    <!-- 配置JobDetail -->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 執行目標job -->
        <property name="targetObject" ref="myJob"></property>

        <!-- 要執行的方法 -->
        <property name="targetMethod" value="execute"></property>
    </bean>

    <!-- 配置tirgger觸發器 -->
    <bean id="cronTriggerFactoryBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!-- jobDetail -->
        <property name="jobDetail" ref="jobDetail"></property>

        <!-- cron表達式,執行時間  每5秒執行一次 -->
        <property name="cronExpression" value="0/5 * * * * ?"></property>
    </bean>

    <!-- 配置調度工廠 -->
    <bean id="springJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="cronTriggerFactoryBean"></ref>
            </list>
        </property>

    </bean>

    <!--<bean id="simpleTrigger"  class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">-->
        <!--&lt;!&ndash;配置具體要執行的jobDetail&ndash;&gt;-->
        <!--<property name="jobDetail" ref="simpleJobDetail" />-->
        <!--&lt;!&ndash;初始延遲時間 1s&ndash;&gt;-->
        <!--<property name="startDelay" value="1000" />-->
        <!--&lt;!&ndash;間隔執行時間每2s執行一次&ndash;&gt;-->
        <!--<property name="repeatInterval" value="2000" />-->
    <!--</bean>-->
</beans>

Job類

package cn.enjoyedu.quartz.xml;

public class CronJob {
    public void execute(){
        System.out.println("定時任務執行...每5秒執行一次");
    }
}

測試類

package cn.enjoyedu.quartz.xml;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringQuartzXmlTest {
    public static void main(String[] args) {
        //啟動spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
        System.out.println("initContext successfully");
    }
}

執行結果

initContext successfully
定時任務執行...每5秒執行一次
定時任務執行...每5秒執行一次

2.註解方式

application.xml

    <!-- 開啟組件掃描 -->
    <context:component-scan base-package="cn.enjoyedu.quartz.annotation"></context:component-scan>
    <!-- 開啟定時任務,spring的定時任務。不是原生quartz -->
    <task:annotation-driven/>

Job class

package cn.enjoyedu.quartz.annotation;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class AnnotationJob {
    @Scheduled(cron = "0/5 * * * * ?")
    public void excute(){
        System.out.println("AnnotationJob 執行 5秒1次");
    }
}

執行結果

initContext successfully
AnnotationJob 執行 5秒1次
AnnotationJob 執行 5秒1次

3.支持數據庫配置cron表達式

3.1TimetaskController

@RequestMapping(value = "/initJob", method = RequestMethod.POST)
    @ResponseBody
    public String initJob() {
        try {
            ObjectResult result = timetaskBiz.initJob();
            return JSONHelper.toJsonDataAPI(result, result.getApiStatus(), result.getErrorMsg());
        } catch (Exception e) {
            return JSONHelper.toJsonErrorDataAPI(e);
        }
    }

3.2 初始化job和啟動job

    /**
     * 初始化job
     * @param timetask
     */
    @Override
    public ObjectResult initJob() {
        ObjectResult result = new ObjectResult();
        try {
            Scheduler scheduler = factoryBean.getScheduler();
            //這裏從數據庫中獲取任務信息數據
            Timetask timetask = new Timetask();
            //0 表示定時任務停止中  1 表示定時任務執行中
            timetask.setJobStatus("0");
            //從數據庫中查詢定時印務記錄。
            List<Timetask> timetaskList =  this.getTimetaskListCus(timetask).getListTimetask();
            for (Timetask task : timetaskList) {
                addJob(task);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
            result.setErrorMsg(e.getMessage());
            result.setApiStatus(ApiData.STATUS_EXCEPTION);
        }
        return result;
    }
    
    

     /**
     * 添加job
     * @param timetask
     */
    private void addJob(Timetask timetask) {
        if(timetask == null || (timetask.getJobStatus() == ScheduleJob.STATUS_RUNNING)) {
            return;
        }

        try {
            Scheduler scheduler = factoryBean.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(timetask.getName(),timetask.getGroupName());
            CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            //如果不存在cronTrigger則重新創建一個
            if(null == cronTrigger){
                Class clazz = null;
                try {
                    clazz = Class.forName(timetask.getBeanClass());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                JobDetail  jobDetail = JobBuilder.newJob(clazz)
                        .withIdentity(timetask.getName(),timetask.getGroupName())
                        .usingJobData("data","")
                        .build();
                jobDetail.getJobDataMap().put("scheduleJob",timetask);
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(timetask.getCron());
                cronTrigger = TriggerBuilder.newTrigger().withDescription(timetask.getIdStr())
                        .withIdentity(timetask.getName(),timetask.getGroupName())
                        .withSchedule(cronScheduleBuilder)
                        .build();

                scheduler.scheduleJob(jobDetail,cronTrigger);
            } else {

                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(timetask.getCron());
                //TODO usingJobData的參數
                cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).usingJobData("data","")
                        .withSchedule(cronScheduleBuilder).build();
                scheduler.rescheduleJob(triggerKey,cronTrigger);
            }
            //執行
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

3.3 job類

package com.zt.uni.api.task.jobs;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("MyJob ... execute ...");
    }
}

package com.zt.uni.api.task.jobs;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MyJob2 implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("MyJob2 ... execute ...");
    }
}

3.4 數據庫配置

技術分享圖片

3.5 執行結果

MyJob ... execute ...
MyJob2 ... execute ...
MyJob ... execute ...
MyJob ... execute ...
MyJob2 ... execute ...
MyJob ... execute ...
MyJob ... execute ...

3.6 存在的問題(最近工作忙,後面再補回來)

  • 如果要支持定時任務可以拔插式使用
  • 要支持圖形界面配置
  • 要支持定時任務在某個時間段期間執行[start_time ,end_time]執行
  • 要支持記錄定時任務的異常信息

Spring集成Quartz的3種方式