动态配置定时任务(Mysql+重启服务后重新加载任务)

jar包版本

		
            org.quartz-scheduler
            quartz
            2.1.1
        

spring版本:3.2.3

1.数据库字段

id(后面用于任务id),
Event(里面可包括任务执行时的相关参数信息),
Status(当前任务状态),
ExecutionTime(任务执行时间),
其余字段更据自己需要配置

2. 需要用到的配置类及工具类##

1.ScheduleJob(任务对象)

package com.kkgame.sspop.schedule.util;

import com.kkgame.sspop.schedule.bean.CampaignScheduleVO;
import com.kkgame.sspop.schedule.bean.OfferScheduleVO;

/**
 * 计划任务信息
 * 
 * User: liyd
 * Date: 14-1-3
 * Time: 上午10:24
 */
public class ScheduleJob {
    /** 任务id */
    private String jobId;
    /** 任务名称 */
    private String jobName;
    /** 任务分组 */
    private String jobGroup;
    /** 任务状态 0禁用 1启用 2删除*/
    private String jobStatus;
    /** 任务运行时间表达式 */
    private String cronExpression;
    /** 任务描述 */
    private String desc;
    /** 任务类型*/
    private int type;
    //
    private CampaignScheduleVO campaignScheduleVO;
    
    private OfferScheduleVO offerScheduleVO;
    
    //get set
	public String getJobId() {
		return jobId;
	}
	public void setJobId(String jobId) {
		this.jobId = jobId;
	}
	public String getJobName() {
		return jobName;
	}
	public void setJobName(String jobName) {
		this.jobName = jobName;
	}
	public String getJobGroup() {
		return jobGroup;
	}
	public void setJobGroup(String jobGroup) {
		this.jobGroup = jobGroup;
	}
	public String getJobStatus() {
		return jobStatus;
	}
	public void setJobStatus(String jobStatus) {
		this.jobStatus = jobStatus;
	}
	public String getCronExpression() {
		return cronExpression;
	}
	public void setCronExpression(String cronExpression) {
		this.cronExpression = cronExpression;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
	public CampaignScheduleVO getCampaignScheduleVO() {
		return campaignScheduleVO;
	}
	public void setCampaignScheduleVO(CampaignScheduleVO campaignScheduleVO) {
		this.campaignScheduleVO = campaignScheduleVO;
	}
	public OfferScheduleVO getOfferScheduleVO() {
		return offerScheduleVO;
	}
	public void setOfferScheduleVO(OfferScheduleVO offerScheduleVO) {
		this.offerScheduleVO = offerScheduleVO;
	}
}

2.QuartzManager(定时任务管理类,任务添加,删除暂停等方法)

package com.kkgame.sspop.schedule.util;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

/**
 * 
 * @Description
 * @author felix
 */
public class QuartzManager {
	private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();  
    private static String JOB_GROUP_NAME = "MY_JOBGROUP_NAME";  
    private static String TRIGGER_GROUP_NAME = "MY_TRIGGERGROUP_NAME";  
  
    /**
     * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
     * @param jobName 任务名
     * @param cls 任务
     * @param time 时间设置,参考quartz说明文档 
     * qgw 2016年1月21日 下午3:30:10 ^_^
     */
    @SuppressWarnings("unchecked")  
    public static void addJob(String jobName, Class cls, String time,Object scheduleJob) {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            JobDetail job = JobBuilder.newJob(cls)
                    .withIdentity(jobName, JOB_GROUP_NAME)
                    .build();
            // 添加具体任务方法
            job.getJobDataMap().put("scheduleJob", scheduleJob);
            // 表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
			// 按新的cronExpression表达式构建一个新的trigger
			Trigger trigger = TriggerBuilder
					.newTrigger()
					.withIdentity(jobName, TRIGGER_GROUP_NAME)
							.withSchedule(scheduleBuilder).build();

            //交给scheduler去调度
			sched.scheduleJob(job, 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说明文档
     * qgw 2016年1月21日 下午3:27:00 ^_^
     */
    @SuppressWarnings("unchecked")  
    public static void addJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName, Class jobClass,  
            String time) {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            JobDetail job = JobBuilder.newJob(jobClass)
                    .withIdentity(jobName, jobGroupName)
                    .build();
            // 表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);
			// 按新的cronExpression表达式构建一个新的trigger
			Trigger trigger = TriggerBuilder
					.newTrigger()
					.withIdentity(triggerName, triggerGroupName)
							.withSchedule(scheduleBuilder).build();
            sched.scheduleJob(job, trigger); 
            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /**
     * @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) 
     * @param jobName
     * @param time
     * qgw 2016年1月21日 下午3:28:34 ^_^
     */
    @SuppressWarnings("unchecked")  
    public static void modifyJobTime(String jobName, String time) { 
    	TriggerKey triggerKey = TriggerKey.triggerKey(
    			jobName, TRIGGER_GROUP_NAME);
    	
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            CronTrigger trigger =(CronTrigger) sched.getTrigger(triggerKey);
            if (trigger == null) {  
                return;  
            }  
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(time)) {
            	CronScheduleBuilder scheduleBuilder =CronScheduleBuilder.cronSchedule(time);
    			//按新的cronExpression表达式重新构建trigger
    			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
    			.withSchedule(scheduleBuilder).build();
    			//按新的trigger重新设置job执行
    			sched.rescheduleJob(triggerKey, trigger);
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /**
     * @Description: 修改一个任务的触发时间 
     * @param triggerName
     * @param triggerGroupName
     * @param time
     * @author qgw 
     * @date 2016年1月27日 下午4:45:15 ^_^
     */
    public static void modifyJobTime(String triggerName,  
            String triggerGroupName, String time) { 
    	TriggerKey triggerKey = TriggerKey.triggerKey(
    			triggerName, triggerGroupName);
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
            if (trigger == null) {  
                return;  
            }  
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(time)) {  
            	// trigger已存在,则更新相应的定时设置
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
		      .cronSchedule(time);
				// 按新的cronExpression表达式重新构建trigger
				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
						.withSchedule(scheduleBuilder).build();
				// 按新的trigger重新设置job执行
				sched.resumeTrigger(triggerKey);
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /**
     * @Description 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
     * @param jobName
     * @author qgw 
     * @date 2016年1月29日 下午2:21:16 ^_^
     */
    public static void removeJob(String jobName) { 
    	TriggerKey triggerKey = TriggerKey.triggerKey(
    			jobName, TRIGGER_GROUP_NAME);
    	JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();
            Trigger trigger = (Trigger) sched.getTrigger(triggerKey);  
            if (trigger == null) {  
                return;  
            }
            sched.pauseTrigger(triggerKey);;// 停止触发器  
            sched.unscheduleJob(triggerKey);// 移除触发器  
            sched.deleteJob(jobKey);// 删除任务  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * @Description: 移除一个任务 
     * @param jobName 
     * @param jobGroupName 
     * @param triggerName 
     * @param triggerGroupName 
     * @author qgw 
     * @date 2016年1月29日 下午2:21:16 ^_^
     */  
    public static void removeJob(String jobName, String jobGroupName,  
            String triggerName, String triggerGroupName) { 
    	TriggerKey triggerKey = TriggerKey.triggerKey(
    			jobName, triggerGroupName);
    	JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler(); 
            sched.pauseTrigger(triggerKey);// 停止触发器  
            sched.unscheduleJob(triggerKey);// 移除触发器  
            sched.deleteJob(jobKey);// 删除任务
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    } 
    /**
     * @Description:暂停一个任务
     * @param jobName
     * @param jobGroupName
     * qgw 2016年1月22日 下午4:24:55 ^_^
     */
    public static void pauseJob(String jobName, String jobGroupName) {
    	JobKey jobKey =JobKey.jobKey(jobName, jobName);
    	try {
    		Scheduler sched = gSchedulerFactory.getScheduler();
			sched.pauseJob(jobKey);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
    /**
     * @Description:暂停一个任务(使用默认组名)
     * @param jobName
     * @param jobGroupName
     * qgw 2016年1月22日 下午4:24:55 ^_^
     */
    public static void pauseJob(String jobName) {
    	JobKey jobKey =JobKey.jobKey(jobName, JOB_GROUP_NAME);
    	try {
    		Scheduler sched = gSchedulerFactory.getScheduler();
    		sched.pauseJob(jobKey);
    	} catch (SchedulerException e) {
    		e.printStackTrace();
    	}
    }
    /** 
     * @Description:启动所有定时任务 
     * @author qgw 
     * @date 2016年1月29日 下午2:21:16 ^_^
     */
    public static void startJobs() {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            sched.start();  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /**
     * @Description 关闭所有定时任务 
     * @author qgw 
     * @date 2016年1月25日 下午2:26:54 ^_^
     */
    public static void shutdownJobs() {  
        try {  
            Scheduler sched = gSchedulerFactory.getScheduler();  
            if (!sched.isShutdown()) {  
                sched.shutdown();  
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    } 
   
}

3.QuartzJobFactory (定时任务运行(反射出来的类),具体执行的操作写在里面)

package com.kkgame.sspop.schedule.util;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.kkgame.sspop.schedule.bean.CampaignScheduleVO;
import com.kkgame.sspop.schedule.bean.OfferScheduleVO;
import com.kkgame.sspop.schedule.service.CampaignScheduleService;
import com.kkgame.sspop.schedule.service.OfferScheduleService;
import com.kkgame.sspop.util.CTX;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 定时任务运行(反射出来的类)
 * @Description
 * @author felix
 * 2016 下午2:39:37 ^_^
 */
@DisallowConcurrentExecution
public class QuartzJobFactory implements Job{
	
	private CampaignScheduleService campaignScheduleService = CTX.getBeanByClass(CampaignScheduleService.class);
	
	private OfferScheduleService offerScheduleService = CTX.getBeanByClass(OfferScheduleService.class);
	
	private static final Logger log = Logger.getLogger("");
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		
		log.info("任务运行开始-------- start --------"); 
		try {
			//ScheduleJob任务运行时具体参数,可自定义
			ScheduleJob scheduleJob =(ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");//(从QuartzManager类中的addJob方法中传入的参数,可自定义)
			
			CampaignScheduleVO campaignScheduleVO = scheduleJob.getCampaignScheduleVO();
			OfferScheduleVO offerScheduleVO = scheduleJob.getOfferScheduleVO();
			
			String event = "";
			
			if(campaignScheduleVO != null){
				event = campaignScheduleVO.getEvent();
			}else if(offerScheduleVO != null){
				event = offerScheduleVO.getEvent();
			}
			
			JSONArray ja = JSONArray.fromObject(event);
			
			for(int i=0;i

4.LoadTask(添加定时任务到进程中)

package com.kkgame.sspop.schedule.util;

import java.util.Date;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 加载定时任务
 * @Description
 * @author qgw
 * 2016 下午2:24:58 ^_^
 */
@SuppressWarnings("unchecked")
public class LoadTask {
	private static final Logger log = Logger.getLogger("");
	/**
	 * @param 执行时间 
	 * @return
	 * @author qgw 
	 * @date 2016年1月26日 下午3:39:13 ^_^
	 */
	public static void timerTask(ScheduleJob job) throws Exception { //doTime 格式为 "2018-03-19 13:50:00"
		
		if(job.getCampaignScheduleVO() != null){//campaign 定时任务
			
			if(!"".equals(job.getCampaignScheduleVO().getExecutionTime())){
				addJob(job, job.getCampaignScheduleVO().getId(), job.getCampaignScheduleVO().getExecutionTime());
			}
			
		}else if(job.getOfferScheduleVO() != null){ // Offer定时任务
			
			if(!"".equals(job.getOfferScheduleVO().getExecutionTime())){
				addJob(job, job.getOfferScheduleVO().getId(), job.getOfferScheduleVO().getExecutionTime());
			}
			
		}
	}
	
	private static void addJob(ScheduleJob job,int id,String time){
		
		String cron = CronFormatUtil.getCron(time);//获得quartz时间表达式,此方法自己写
		
		String jobName = id+"_job";
		
		job.setJobId(id+"");
		job.setJobName(jobName);
		job.setCronExpression(cron);
		job.setJobGroup("MY_JOBGROUP_NAME");
		
		//删除已有的定时任务
		QuartzManager.removeJob(jobName);
		//添加定时任务
		QuartzManager.addJob(jobName, QuartzJobFactory.class, cron,job);
	}
	
	public static void updateStatus(ScheduleJob job){
		
		String jobName = "";
		
		if(job.getCampaignScheduleVO() != null){
			jobName = job.getCampaignScheduleVO().getId()+"_job";
		}else if(job.getOfferScheduleVO().getId()>0){
			jobName = job.getOfferScheduleVO().getId()+"_job";
		}
		
		try {
			//删除已有的定时任务
			QuartzManager.removeJob(jobName);
		} catch (Exception e) {
			log.info("加载定时器错误:"+e);
		}
		
	}
	
	//启动项目时加载所有未执行的任务
	@PostConstruct
	public void initSchedule(){
		
		try {
			
			//初始化offer定时任务 start
			List initOfferScheduleList = offerScheduleService.getInitOfferScheduleList();
			for(int i=0;i initCampaignScheduleList = campaignScheduleService.getInitCampaignScheduleList();
			for(int i=0;i

5.CronFormatUtil(“2011-07-09 18:00:00” 字符串转 cron格式时间)

package com.kkgame.sspop.schedule.util;

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

/**
 * 
 * @author felix
 * @Description "2011-07-09 18:00:00" 字符串转 cron格式时间
 */

public class CronFormatUtil {
	
	/*** 
     *  
     * @param date 
     * @param dateFormat : e.g:yyyy-MM-dd HH:mm:ss 
     * @return 
     */  
    public static String formatDateByPattern(Date date,String dateFormat){  
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);  
        String formatTimeStr = null;  
        if (date != null) {  
            formatTimeStr = sdf.format(date);  
        }  
        return formatTimeStr;  
    }  
    /*** 
     * convert Date to cron ,eg.  "0 06 10 15 1 ? 2014" 
     * @param date  : 时间点 
     * @return 
     */  
    public static String getCron(String   dateString){ //"2011-07-09 18:00:00"
    	SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
        String dateFormat="ss mm HH dd MM ? yyyy";  
        
        Date date = null;
		try {
			date = formatter.parse(dateString);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
        return formatDateByPattern(date, dateFormat);  
    }
    
    public static void main(String[] args) {
    	System.out.println(getCron("2018-03-19 18:01:02"));
	}

}

3任务动态执行流程

1.前台添加任务将数据保存到后台

a.前台发送相应的动态定时任务配置信息,
b.后台接收后先处理信息并保存到数据库,并返回当前任务的Id.

OfferScheduleVO offerScheduleTemp;
		offerScheduleTemp = offerScheduleDao.createOfferScheduleVO(offerScheduleVO);

c.将数据添加到进程任务中去

//添加到任务列
		ScheduleJob job = new ScheduleJob();
		
		job.setOfferScheduleVO(offerScheduleTemp);
		
		LoadTask.timerTask(job);

此时定时任务已添加可以查看执行结果

2.程序重启时将数据库中未执行且未过时的任务加入任务进程中
查看 LoadTask中的initSchedule()方法注意要加上@PostConstruct注解(具体意思自己百度)

看NBA会员直播 看个球www.kangeqiu.top

你可能感兴趣的:(spring,定时任务)