Quartz定时任务调度

一、简介
   Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz 允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。虽然可以通过属性文件(在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问 Web 服务器的内部函数;例如,在使用 WebSphere 应用服务器时,由 Quartz 调度的作业并不能影响服务器的动态缓存和数据源。
二、要使用Quartz,需要引入以下包
  1、log4j-1.2.16
  2、quartz-2.1.7
  3、slf4j-api-1.6.1.jar
  4、slf4j-log4j12-1.6.1.ja
三、了解几个接口
首先了解三个概念:
调度器 (Scheduler): 负责调度作业和触发器;
 
触发器(trigger)      设置作业执行的时间、参数、条件等;(简单触发器和Cron触发器)
 
 作业(Job)             :定时任务内容,被执行的程序;
下载必要的jar包,直接去官网下载 (http://www.opensymphony.com/quartz/download.action),将quartz-x.x.x.jar 和core 和/或 optional 文件夹中的 jar 文件放在项目的文件夹或项目的类路径中
 
四、Quartz的几个核心的接口和类
Job接口:  自己写的“定时程序”实现此接口的void execute(JobExecutionContext arg0)方法,Job还有一类为有状态的StatefulJob接口,如果我们需要在上一个作业执行完后,根据其执行结果再进行下次作业的执行,则需要实现此接口。
Trigger抽象类:  调度类(Scheduler)在时间到时调用此类,再由trigger类调用指定的定时程序。
Quertz中提供了两类触发器为:SimpleTrigger,CronTrigger。前者用于实现比较简单的定时功能,例如几点开始,几点结束,隔多长时间执行,共执行多少次等,后者提供了使用表达式来描述定时功能,因此适用于比较复杂的定时描述,例如每个月的最后一个周五,每周的周四等。
 
JobDetail类:  具体某个定时程序的详细描述,包括Name,Group,JobDataMap等。
JobExecutionContext类:  定时程序执行的run-time的上下文环境,用于得到当前执行的Job的名字,配置的参数等。
JobDataMap类:  用于描述一个作业的参数,参数可以为任何基本类型例如String,float等,也可为某个对象的引用.
JobListener,TriggerListener接口:  用于监听触发器状态和作业扫行状态,在特写状态执行相应操作。
JobStore类:  在哪里执行定进程序,可选的有在内存中,在数据库中。
 
四、下面来配置Quartz框架在Spring中的引用
    1.新建一个定时任务管理类,命名为QuartzJobManager
package com.shpte.paramfrm.quartz;

import java.util.Map;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Controller;

/**
 * @Description: 定时任务管理类
 * 
 * @ClassName: QuartzJobsManager
 */

@Controller
public class QuartzJobsManager
{

    @Autowired
    private SchedulerFactoryBean schedulerFactory;
    
    private  String JOB_GROUP_NAME = "AFC_JOBGROUP_NAME";
    private  String TRIGGER_GROUP_NAME = "AFC_TRIGGERGROUP_NAME";

    /**
     * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
     * 
     * @param jobName
     *            任务名
     * @param cls
     *            任务
     * @param time
     *            时间设置,参考quartz说明文档
     * 
     */
    
    @SuppressWarnings("unchecked")
    public void addJob(String jobName, Class cls, String time)
    {
        try
        {
            
            Scheduler sched = schedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类
            // 触发器
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
            
            // 启动
            if (!sched.isShutdown())
            {
                sched.start();
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
    
    @SuppressWarnings("unchecked")
    public  void addJob(String jobName, Class cls, String time, Map<String, Object> jobDataMap)
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类
            jobDetail.getJobDataMap().putAll(jobDataMap);
            // 触发器
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
            // 启动
            if (!sched.isShutdown())
            {
                sched.start();
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 添加一个定时任务
     * 
     * @param jobName
     *            任务名
     * @param jobGroupName
     *            任务组名
     * @param triggerName
     *            触发器名
     * @param triggerGroupName
     *            触发器组名
     * @param jobClass
     *            任务
     * @param time
     *            时间设置,参考quartz说明文档
     */
    @SuppressWarnings("unchecked")
    public  void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String time)
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass);// 任务名,任务组,任务执行类
            // 触发器
            CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
     * 
     * @param jobName
     * @param time
     */
    @SuppressWarnings("unchecked")
    public  void modifyJobTime(String jobName, String time)
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
            if (trigger == null)
            {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time))
            {
                JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);
                Class objJobClass = jobDetail.getJobClass();
                removeJob(jobName);
                addJob(jobName, objJobClass, time);
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 修改一个任务的触发时间
     * 
     * @param triggerName
     * @param triggerGroupName
     * @param time
     */
    public  void modifyJobTime(String triggerName, String triggerGroupName, String time)
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);
            if (trigger == null)
            {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time))
            {
                CronTrigger ct = (CronTrigger) trigger;
                // 修改时间
                ct.setCronExpression(time);
                // 重启触发器
                sched.resumeTrigger(triggerName, triggerGroupName);
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
     * 
     * @param jobName
     */
    public  void removeJob(String jobName)
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器
            sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
            sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 移除一个任务
     * 
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */
    public  void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName)
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器
            sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器
            sched.deleteJob(jobName, jobGroupName);// 删除任务
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:启动所有定时任务
     */
    public  void startJobs()
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            sched.start();
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:关闭所有定时任务
     * 
     */
    public  void shutdownJobs()
    {
        try
        {
            Scheduler sched = schedulerFactory.getScheduler();
            if (!sched.isShutdown())
            {
                sched.shutdown();
            }
        } catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
}
2、新建一个QuartzTestJob类来实现Job接口
package com.shpte.paramfrm.quartz.jobs;

import java.text.SimpleDateFormat;
import java.util.Date;

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

public class QuartzTestJob implements Job
{

    @Override
    public void execute(JobExecutionContext jobCtx) throws JobExecutionException
    {
        // jobCtx.getJobDetail().getJobDataMap().get(key)
        
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "★★★★★★★★★★★");
        //QuartzJobsManager.removeJob("动态任务调度");
    }

}

 

3、开始将Quartz与Spring整合
  
 (1)、新建一个JobFactory继承AdaptableJobFactory类
package com.shpte.paramfrm.quartz.jobs;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;


public class JobFactory extends AdaptableJobFactory {  
    
    @Autowired  
    private AutowireCapableBeanFactory capableBeanFactory;  
  
    @Override  
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {  
        //调用父类的方法  
        Object jobInstance = super.createJobInstance(bundle);  
        //进行注入  
        capableBeanFactory.autowireBean(jobInstance);  
        return jobInstance;  
    }  
      
}
(2)、新建一个applicationContext-quartz.xml文件,注入Quartz到Spring
   
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
        default-lazy-init="true">

    <description>定时任务</description>
    
    <bean id="schedulerFactoryBean" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" scope="singleton">
        <property name="jobFactory">
            <bean class="com.shpte.paramfrm.quartz.jobs.JobFactory"></bean>  
        </property>  
    </bean>
        
</beans>

 

4、新建一个Job任务
package com.shpte.paramfrm.quartz.jobs;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.shpte.common.param.manager.DraftParamManager;
import com.shpte.dubbo.provider.IDraftParamService;


public class QuartzEffectDraftParamLCC implements StatefulJob
{
    private static final Logger log = LoggerFactory.getLogger(QuartzEffectDraftParamLCC.class);
    
    public static final String DEFAULT_JOB_NAME = "HBparam";    //这个 DEFAULT_JOB_NAME只给Quartz用
    //0 0/30 * * * ?  每隔一分钟  执行一次   0 */1 * * * ? 
    public static final String DEFAULT_JOB_TIME = " 0 5 9 22 2 ? 2017 "; //这个 DEFAULT_JOB_TIME只给Quartz用
    
    public static final Integer REPLY_TIME_OUT = 300000;

    @Autowired
    public DraftParamManager draftParamManager;
    
    @Autowired
    public IDraftParamService draftParamService;

    @Override
    public void execute(JobExecutionContext jobCtx) throws JobExecutionException
    {
        log.info(" ★★★★★★★★★★★ 开始执行任务 : " + jobCtx.getJobDetail().getName());
        
        if (!draftParamManager.effectiveDraftParam("DraftParamLcc",TinyTools.nowStr())))
        {
            log.info("-----草稿参数生效失败------");
        } else
        {
            log.info("-----草稿参数生效成功------");
        }
        return;
    }

}

 

5、添加一个Init()方法,调用任务类并且运行
  这里调用了有三个任务,上面我只写了一个任务。
@PostConstruct
    private void init()
    {
        log.info(" ★★★★★★★★★★★ 启动默认任务 : " + QuartzEffectFutureParamCCHS.DEFAULT_JOB_NAME +" 触发时间:" + QuartzEffectFutureParamCCHS.DEFAULT_JOB_TIME);
        quartzJobsManager.addJob(QuartzEffectFutureParamCCHS.DEFAULT_JOB_NAME, QuartzEffectFutureParamCCHS.class, QuartzEffectFutureParamCCHS.DEFAULT_JOB_TIME);
        
        log.info(" ★★★★★★★★★★★ 启动默认任务 : " + QuartzEffectFutureParamLCC.DEFAULT_JOB_NAME +" 触发时间:" + QuartzEffectFutureParamLCC.DEFAULT_JOB_TIME);
        quartzJobsManager.addJob(QuartzEffectFutureParamLCC.DEFAULT_JOB_NAME, QuartzEffectFutureParamLCC.class, QuartzEffectFutureParamLCC.DEFAULT_JOB_TIME);
        
        log.info(" ★★★★★★★★★★★ 启动默认任务 : " + QuartzEffectDraftParamLCC.DEFAULT_JOB_NAME +" 触发时间:" + QuartzEffectDraftParamLCC.DEFAULT_JOB_TIME);
        quartzJobsManager.addJob(QuartzEffectDraftParamLCC.DEFAULT_JOB_NAME, QuartzEffectDraftParamLCC.class, QuartzEffectDraftParamLCC.DEFAULT_JOB_TIME



总结:以上就是一个完整的Quartz框架搭建、在Spring中整合、以及定制一个任务来在定时定点触发执行的完成步骤及完整代码。
);
        loadParam();
    }

 

6、看控制台日志
  
 
 
posted @ 2017-07-28 13:49  像艳遇一样忧伤c  阅读(378)  评论(0编辑  收藏  举报