package com.deliverik.infogovernor.scheduling.jobs;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import com.deliverik.framework.platform.WebApplicationSupport;
public class JobManager {
private static Scheduler scheduler = WebApplicationSupport.getScheduler();
private static String JOB_GROUP_NAME = "job_group";
public static String TRIGGER_GROUP_NAME = "trigger_group";
private static Log log = LogFactory.getLog(JobManager.class);
/**
* 添加job
*
* @param jobName job名称
* @param jobGroupName job组名
* @param triggerName 触发器名称
* @param triggerGroupName 触发器组名
* @param job job类
* @param argsMap 参数集合
* @param cronExpression 时间表达式
* @param startTime 开始时间
* @param endTime 结束时间
* @throws SchedulerException
* @throws ParseException
*/
public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
Job job, Map<String,Object> argsMap, String cronExpression, Date startTime,Date endTime)
throws SchedulerException, ParseException {
//Scheduler就是Quartz的大脑,所有任务都是由它来设施。
// JobDetail jobDetail = new JobDetail(jobName, jobGroupName, job.getClass());
JobBuilder jobBuilder = JobBuilder.newJob(job.getClass());
jobBuilder.withIdentity(jobName, jobGroupName);
//JobDetail – (作业实例)定义Job的实例;
JobDetail jobDetail = jobBuilder.build();
// CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);
// 每两秒执行
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(
CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing()
).build();
//定义和创建Trigger实例的接口;
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression));
//Trigger – (触发器)触发Job的执行;
// Trigger trigger = triggerBuilder.build();
Set<String> argsKeys = argsMap.keySet();
Iterator<String> keysIterator = argsKeys.iterator();
while (keysIterator.hasNext()) {
String key = keysIterator.next();
jobDetail.getJobDataMap().put(key, argsMap.get(key));
}
try {
CronTriggerImpl ct = (CronTriggerImpl) trigger;
ct.setCronExpression(cronExpression);
if (null != startTime) ct.setStartTime(startTime);
if (null != endTime) ct.setEndTime(endTime);
scheduler.scheduleJob(jobDetail, ct);
if (!scheduler.isShutdown())
scheduler.start();
} catch (ParseException e) {
log.error("trigger.setCronExpression(cronExpression) Exception: ",e);
} catch (SchedulerException e) {
log.error("scheduler.scheduleJob(jobDetail, trigger) Exception: ",e);
throw new SchedulerException();
}
}
}
withMisfireHandlingInstructionDoNothing 这个挺有用的不设置这个属性,每一次修改保存后,job都会执行一遍
建一个类实现Job
public class ScheduleProcessJob implements Job {
private static Log log = LogFactory.getLog(ScheduleProcessJob.class);
public void execute(JobExecutionContext context) throws JobExecutionException {
log.debug("====================计划任务-流程发起,开始======================");
// 获取参数
Map<?, ?> map = context.getJobDetail().getJobDataMap();
String sctid = (String) map.get("SCTID");
String[] pdidList = (String[]) map.get("pdid");
try {
if (StringUtils.isEmpty(sctid)) {
log.warn("========计划任务信息不存在========");
return;
}
//具体业务逻辑
} catch (Exception e) {
log.error("========计划任务发起流程失败:" + e.getMessage() + "========");
e.printStackTrace();
}
log.debug("====================计划任务-流程发起,结束======================");
}
}
/**
* 创建定时任务
* @param sct001
* @throws BLException
*/
private void createSctJob(SCT002Info sct002,IGSCT0202Form igSCT0202form) throws BLException {
log.info("创建定时任务开始");
// 表达式
String cronExpression = "";
// 任务名
String jobName = "";
// 任务组名
String jobGroupName = "SctJobGroup" + sct002.getSctid();
// 任务触发器名
String triggerName = "";
// 任务触发器组名
String triggerGroupName = "SctTriggerGroup" + sct002.getSctid();
// 开始时间
Date beganDate = null;
// 结束时间
Date endDate = null;
// 任务提前生成时间
Integer preDay = Integer.parseInt(sct002.getSctpretime().split("#")[0]);
Integer preHour = Integer.parseInt(sct002.getSctpretime().split("#")[1]);
Integer preMinute = Integer.parseInt(sct002.getSctpretime().split("#")[2]);
try {
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm");
beganDate = format.parse(sct002.getSctstarttime() + " 00:00");
Calendar calendar = Calendar.getInstance();
calendar.setTime(beganDate);
calendar.add(Calendar.DATE, -preDay);
calendar.add(Calendar.HOUR, -preHour);
calendar.add(Calendar.MINUTE, -preMinute);
beganDate = calendar.getTime();
endDate = format.parse(sct002.getSctendtime() + " 23:59");
calendar.setTime(endDate);
calendar.add(Calendar.DATE, -preDay);
calendar.add(Calendar.HOUR, -preHour);
calendar.add(Calendar.MINUTE, -preMinute);
endDate = calendar.getTime();
} catch (ParseException e) {
log.error("计划任务日期格式不正确", e);
throw new BLException("IGCO10000.E141", "计划任务日期格式不正确!");
}
// 参数
List<String> keyname = new ArrayList<String>();
keyname.add("SCTID");
keyname.add("USERID");
Map<String, Object> args = new HashMap<String, Object>();
args.put("SCTID", String.valueOf(sct002.getSctid()));
args.put("USERID", sct004Info.getSctdealuserid());
args.put("DEALTIME", sct004Info.getScthour() + ":" + sct004Info.getSctminute());
cronExpression = creatCronExp(sct002, sct003Info, sct004Info);
try {
JobManager.addJob(jobName, jobGroupName, triggerName, triggerGroupName, new ScheduleProcessJob(), args, cronExpression);
} catch (Exception e) {
throw new BLException("IGCO10000.E141", "计划任务设置失败!");
}
log.info("创建定时任务结束");
}
/**
* 生成表达式
*
* @param sct002Info
* @param sct003Info
* @param sct004Info
* @return
*/
private String creatCronExp(SCT002Info sct002Info, SCT003Info sct003Info, SCT004Info sct004Info) throws BLException {
//quartz执行表达式
String retCronExp = null;
String type = sct002Info.getSctcycletype();
String cycle = sct002Info.getSctcycledesc();
Integer hour = Integer.parseInt(sct004Info.getScthour());
Integer minute = Integer.parseInt(sct004Info.getSctminute());
String cron = "";
// 任务提前生成时间
Integer preDay = Integer.parseInt(sct002Info.getSctpretime().split("#")[0]);
Integer preHour = Integer.parseInt(sct002Info.getSctpretime().split("#")[1]);
Integer preMinute = Integer.parseInt(sct002Info.getSctpretime().split("#")[2]);
// 计算提前后的生成时间
minute = minute - preMinute;
if (minute < 0) {
minute = minute + 60;
preHour++;
}
hour = hour - preHour;
if (hour < 0) {
hour = hour + 24;
preDay++;
}
//秒 分 时 日 月 周
if ("每日".equals(type)) {
retCronExp = "0 " + minute + " " + hour + " * * ?";
} else if ("每周".equals(type)) {
preDay = preDay%7;
String[] weeks = cycle.split("#");
for (String week : weeks) {
Integer wcorn = Integer.parseInt(week) - preDay;
if (wcorn < 0) {
cron += "," + (wcorn + 8);
} else {
cron += "," + (wcorn + 1);
}
}
cron = cron.substring(1);
retCronExp = "0 " + minute + " " + hour + " ? * " + cron;
} else if ("每月".equals(type)) {
String[] months = cycle.split("#");
for (String month : months) {
Integer mcorn = Integer.parseInt(month) - preDay;
String addmonth = "";
if (mcorn < 1) {
addmonth = -(mcorn-1) + "L";
} else {
addmonth = "" + mcorn;
}
cron += "," + addmonth;
}
cron = cron.substring(1);
retCronExp = "0 " + minute + " " + hour + " " + cron + " * ?";
} else if ("不定期".equals(type)) {
String scttime = sct003Info.getScttime();
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
try {
Date date = format.parse(sct003Info.getScttime());
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, -preDay);
scttime = format.format(calendar.getTime());
} catch (ParseException e) {
log.error("日期格式化异常", e);
throw new BLException("IGCO10000.E141", "日期格式化异常!");
}
Integer day = Integer.parseInt(scttime.split("/")[2]);
Integer month = Integer.parseInt(scttime.split("/")[1]);
String year = scttime.split("/")[0];
retCronExp = "0 " + minute + " " + hour + " " + day + " " + month + " ? " + year;
}
log.debug(retCronExp);
return retCronExp;
}
/**
* 删除定时任务
* @param sct001
* @throws BLException
*/
private void deleteSctJob(SCT002Info sct002) throws BLException {
// 任务名
String jobName = "";
// 任务组名
String jobGroupName = "SctJobGroup" + sct002.getSctid();
// 任务触发器名
String triggerName = "";
// 任务触发器组名
String triggerGroupName = "SctTriggerGroup" + sct002.getSctid();
try {
JobManager.removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
} catch (Exception e) {
throw new BLException("IGCO10000.E141", "计划任务删除失败!");
}
}