使用Quartz配置动态定时任务(总结)

来源:互联网 发布:淘宝类目在哪里设置 编辑:程序博客网 时间:2024/05/20 07:52

应用场景:需要在一个指定日期的前一天的23点59分来触发这个定时任务

这里分为三个主要的步骤:

1.编写一个定时任务工具类:ScheduleUtils

2.编写一个执行任务类(实现job类):CheckInocPlanJob implements Job

3.调用定时工具类的方法来触发定时任务

1.编写一个定时任务工具类:ScheduleUtils

package com.zhite.common.utils;
import java.util.Properties;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.ScheduleBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*定时任务工具类
*/
public class ScheduleUtils {

private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class);
private static StdSchedulerFactory sf = null;
private Scheduler sched = null;
private Class<? extends Job> jobClass;//执行任务的类
private String exp;//表达式
private String jobName;//job名称
private String jobGroup;//job组名称
private String triggerName;//触发器名称
private String triggerGroup;//触发器组名称

public static StdSchedulerFactory getSchedulerFactory(){//获得调度工厂
if(sf==null) {
return new StdSchedulerFactory();
}
return sf;
}

/**
* 构造方法
* @param tmp 关键字,区分_scheduler实例的
* @param exp 时间表达式
* @param jobClass 执行的job类
* @param jobNamejob名成
* @param triggerGroup 触发器组名称
* @param jobGroupjob组名
* @param triggerName 触发器名称
*/
public ScheduleUtils(String tmp,String exp, Class<? extends Job> jobClass, String jobName, String triggerGroup, String jobGroup, String triggerName){
try {
this.jobClass = jobClass;
this.exp = exp;
this.jobName = jobName;
this.triggerGroup = triggerGroup;
this.jobGroup = jobGroup;
this.triggerName =triggerName;
Properties props = new Properties();
props.put("org.quartz.scheduler.instanceName",tmp+"_scheduler");
props.put("org.quartz.threadPool.threadCount", "10");
props.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
sf=ScheduleUtils.getSchedulerFactory();
sf.initialize(props);
sched = sf.getScheduler();
Scheduler sched = sf.getScheduler(tmp+"_scheduler");
Scheduler sched1 = sf.getScheduler(jobName);
if (null!=sched1) {
if (sched1.isStarted()) {
sched1.shutdown();
}
}
if (null!=sched) {
if (sched.isStarted()) {
sched.shutdown();
}
}
log.info(sched.getSchedulerName());
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 开始定时任务
*/
public void startScheduler() {
try {
sched.start();
log.info("调度任务启动...");
} catch (SchedulerException e) {
e.printStackTrace();
}
}

/**
* 添加调度任务
* @throws Exception
*/
public void addJob(JobDetail job ,Trigger trigger) throws Exception {
//作业和触发器注册到任务调度中
sched.scheduleJob(job, trigger);
}
/**
* 为JobDetail添加参数
* @throws Exception
*/
public JobDetail getJobDetail()throws Exception{
JobDetail job=JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();
return job;
}
/**
* 获得SimpleTrigger触发器
* SimpleScheduleBuilder.repeatSecondlyForever(1).withRepeatCount(8)
* @return
*/
public Trigger getSimpleTrigger(ScheduleBuilder<?> schedule){
      Trigger trigger=TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)  
      .withSchedule(schedule)  
      .startNow().build(); 
return trigger;
}

/**
* 获得CornTrigger触发器
* @return
*/
public Trigger getCornTrigger(){
Trigger trigger=TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroup)  
.withSchedule(CronScheduleBuilder.cronSchedule(exp))  
.startNow().build();
return trigger;
}

/** 
     * @Description: 修改一个任务的触发时间
     *  
     * @param jobName 
     * @param jobGroupName
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名 
     * @param cron   时间设置,参考quartz说明文档   
     */  
    public static void modifyJobTime(String jobName, 
            String jobGroupName, String triggerName, String triggerGroupName, String cron) {  
        try { 
        Scheduler sched =sf.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger)sched.getTrigger(triggerKey);  
            if (trigger == null) {  
                return;  
            }  


            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(cron)) { 
                /** 方式一 :调用 rescheduleJob 开始 */
                // 触发器  
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组  
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 触发器时间设定  
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一个任务的触发时间
                sched.rescheduleJob(triggerKey, trigger);
                /** 方式一 :调用 rescheduleJob 结束 */


                /** 方式二:先删除,然后在创建一个新的Job  */
                //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));  
                //Class<? extends Job> jobClass = jobDetail.getJobClass();  
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 
                /** 方式二 :先删除,然后在创建一个新的Job */
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  


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


/**
* 停止定时任务
*/
public void stopScheduler() {
try {
//也可以在jocClass中这样停止context.getScheduler().shutdown();
sched.shutdown();
log.info("调度任务停止...");
} catch (SchedulerException e) {
e.printStackTrace();
}
}


public Class<?> getJoblass() {
return jobClass;
}


public void setJoblass(Class<? extends Job> jobClass) {
this.jobClass = jobClass;
}


public Scheduler getSched() {
return sched;
}


public void setSched(Scheduler sched) {
this.sched = sched;
}


public String getExp() {
return exp;
}


public void setExp(String exp) {
this.exp = exp;
}


public String getJobName() {
return jobName;
}


public void setJobName(String jobName) {
this.jobName = jobName;
}


public String getGroup() {
return triggerGroup;
}


public void setGroup(String group) {
this.triggerGroup = group;
}


public String getJobGroup() {
return jobGroup;
}


public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}


public String getTriggerName() {
return triggerName;
}


public void setTriggerName(String triggerName) {
this.triggerName = triggerName;
}

}

2.编写一个执行任务类(实现job类):定时任务(定时任务做的事)

package com.zhite.biz.service.qa.impl;
import java.util.Date;
import java.util.Map;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zhite.biz.service.checkInocPlan.CheckInocPlanService;
import com.zhite.common.utils.JsonResult;
/**
 *  需要执行的任务  
 * @author lizhiling
 *
 */
@Service
public class CheckInocPlanJob implements Job{
@Autowired
private CheckInocPlanService checkInocPlanService;
@Override
//把要执行的操作,写在execute方法中  
public void execute(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
System.out.println("测试定时任务类"+new Date());
Map<String, Object> parameter=context.getJobDetail().getJobDataMap().getWrappedMap();
System.out.println(parameter.get("name"));
try {
//定时任务进行的方法(此处写你们自己的任务)
JsonResult jsonResult=checkInocPlanService.createFrameData(parameter);
System.out.println(jsonResult.getMsg());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


   
}

3.调用定时工具类的方法来触发定时任务:


/**
* 开始定时任务
*/
private void runScheduler(Map<String, Object> parameter){
//获取开展日期的前一天
  Date date = null;
try {
date = getBeforeDay(new SimpleDateFormat("yyyy/MM/dd").parse(parameter.get("startdate").toString()));
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String jobName=parameter.get("startdate").toString()+"jobname"+parameter.get("companyid").toString();
//日期转换cron表达式(注意:日期表达式需在当前日期之后,不然报错:never fire)
String cornExp=new SimpleDateFormat("0 0 23 dd MM ? yyyy").format(date);
ScheduleUtils scheduleUtils=new ScheduleUtils("TMP"+jobName,cornExp, CheckInocPlanJob.class, jobName, "triggerGroup", "jobGroup", "triggerName");
try {
JobDetail jobDetail=scheduleUtils.getJobDetail();
Trigger trigger=scheduleUtils.getCornTrigger();
jobDetail.getJobDataMap().putAll(parameter);//传递map给job类
scheduleUtils.addJob(jobDetail,trigger);
scheduleUtils.startScheduler();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
scheduleUtils.stopScheduler();
}
}
/**
* 根据日期获取前一天
* @param date 日期
* @return
*/
    private Date getBeforeDay(Date date) {  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.add(Calendar.DAY_OF_MONTH, -1);  
        date = calendar.getTime();  
        return date;  
    }  

##############################################################

在需要调用的地方调用runScheduler() 方法即可