public abstract class BaseJob { /** * */ private static final long serialVersionUID = -750342144932125596L; public BaseJob() { } private Job job = new Job(); public Job getJob() { return job; } public void setJob(Job job) { this.job = job; } private Scheduler scheduler; // 通过setter方法传入被调用者的实例scheduler public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } public Scheduler getScheduler() { return scheduler; } public void reScheduleJob() throws SchedulerException, ParseException { MyCronTrigger trigger = (MyCronTrigger) this.getScheduler().getTrigger( this.getJob().getTriggerName(), Scheduler.DEFAULT_GROUP); this.setJob(trigger.getScheduleInfoManager().queryJobInfo(this).getJob()); // 如果job表中的status!=P 就不启动这个job if (!this.getJob().getStatus().equalsIgnoreCase("P")) { this.getScheduler().pauseJob(this.getJob().getName(), Scheduler.DEFAULT_GROUP); return; } else { this.getScheduler().resumeJob(this.getJob().getName(), Scheduler.DEFAULT_GROUP); } // ConExpressionTransfer.convertDateToCro nExp(everyWhat, commonNeeds, monthlyNeeds, // weeklyNeeds, userDefinedNeeds); System.out.println("首次时间 >>>> " + trigger.getOrigTime());// 初始 String lastCronExpression = trigger.getCronExpression(); // 上次时间 System.out.println("上次时间 >>>> " + lastCronExpression); String newCronExpression = this.getJob().getRuntime();// 新时间 System.out.println("新时间 >>>> " + newCronExpression); if (!lastCronExpression.equalsIgnoreCase(newCronExpression)) { System.out.println(" ..时间有变化...从 " + lastCronExpression + " 到 " + newCronExpression); System.out.println(" 重置 CronExpression "); trigger.setCronExpression(newCronExpression); this.getScheduler().rescheduleJob(this.getJob().getTriggerName(), Scheduler.DEFAULT_GROUP, trigger); } else { // 下面是执行具体的job内容 System.out.println(" ..时间没有变化..."); this.execute(); } } public abstract void execute(); }
public class PrintJob extends BaseJob { public PrintJob() { super(); this.getJob().setTriggerName("printJobTrigger"); JobRegistry.registerJob(this); } @Override public void execute() { // 执行入口函数 // 业务逻辑 System.out.println("PrintJOB over = " + DateTimeUtil.currentTime()); System.out.println(JobRegistry.getJob("printJobTrigger").getJob().getTriggerName()); } }
所有要执行的job都必须来这里注册 public class JobRegistry { /* * Map<jobTriggerName,BaseJob> */ private static Map<String, BaseJob> jobMap = new HashMap<String, BaseJob>(); public static void registerJob(BaseJob job) { jobMap.put(job.getJob().getTriggerName(), job); } public static BaseJob getJob(String triggerName) { return jobMap.get(triggerName); } }
public class MyCronTrigger extends CronTriggerBean { private BaseJob job; public BaseJob getJob() { return job; } public void setJob(BaseJob job) { this.job = job; } private ScheduleInfoManager scheduleInfoManager; public ScheduleInfoManager getScheduleInfoManager() { return scheduleInfoManager; } // 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager) { System.out.println("InitializingCronTrigger........."); this.scheduleInfoManager = scheduleInfoManager; String cronExpression = scheduleInfoManager.queryJobInfo(job).getJob().getRuntime(); this.origTime = cronExpression; try { System.out.println(cronExpression); setCronExpression(cronExpression); } catch (ParseException e) { e.printStackTrace(); } } private String origTime; public String getOrigTime() { return origTime; } /** * @param origTime the origTime to set */ public void setOrigTime(String origTime) { this.origTime = origTime; } }
/** * 获取任务时间 * * @return */ protected String getRuntime() { HttpServletRequest request = ServletActionContext.getRequest(); String everyWhat = request.getParameter("everyWhat"); if ("Immediate Processing".equals(everyWhat)) { System.out.println("立即执行。。。。"); String time = new SimpleDateFormat("HH:mm:ss").format(new Date()); String[] commonNeeds = { time.split(":")[2], time.split(":")[1], time.split(":")[0] }; String userDefinedNeeds = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); String[] monthlyNeeds = { request.getParameter("week"), request.getParameter("dayOfWeek") }; String weeklyNeeds = (String) request.getParameter("dayOfWeek"); cronExpression = CronExpConversion.convertDateToCronExp(everyWhat, commonNeeds, monthlyNeeds, weeklyNeeds, userDefinedNeeds); } else { String time = request.getParameter("time"); String[] commonNeeds = { time.split(":")[2], time.split(":")[1], time.split(":")[0] }; String[] monthlyNeeds = { request.getParameter("week"), request.getParameter("dayOfWeek") }; String weeklyNeeds = (String) request.getParameter("dayOfWeek"); String userDefinedNeeds = request.getParameter("date"); cronExpression = CronExpConversion.convertDateToCronExp(everyWhat, commonNeeds, monthlyNeeds, weeklyNeeds, userDefinedNeeds); } return cronExpression; }
public class CronExpConversion { /** * 页面设置转为UNIX cron expressions 转换算法 * * @param everyWhat * @param commonNeeds 包括 second minute hour * @param monthlyNeeds 包括 第几个星期 星期几 * @param weeklyNeeds 包括 星期几 * @param userDefinedNeeds 包括具体时间点 * @return cron expression */ public static String convertDateToCronExp(String everyWhat, String[] commonNeeds, String[] monthlyNeeds, String weeklyNeeds, String userDefinedNeeds) { String cronEx = ""; String commons = commonNeeds[0] + " " + commonNeeds[1] + " " + commonNeeds[2] + " "; String dayOfWeek = ""; if ("weekly".equals(everyWhat)) { dayOfWeek = weeklyNeeds; // 1 if (dayOfWeek != null) { cronEx = (commons + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " " + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " " + dayOfWeek + " ").trim(); } else { cronEx = (commons + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " " + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " " + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " ").trim(); } } else if ("Daily".equals(everyWhat)) { cronEx = (commons + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " " + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " " + CronExRelated.specialCharacters.get(CronExRelated._EVERY) + " ").trim(); } else {// 立即执行--将定时任务的时间设置为当前时间 String dayOfMonth = userDefinedNeeds.split("-")[2]; if (dayOfMonth.startsWith("0")) { dayOfMonth = dayOfMonth.replaceFirst("0", ""); } String month = userDefinedNeeds.split("-")[1]; if (month.startsWith("0")) { month = month.replaceFirst("0", ""); } String year = userDefinedNeeds.split("-")[0]; // FIXME 暂时不加年份 Quartz报错 /* * cronEx = (commons + dayOfMonth + " " + month + " " + * CronExRelated.specialCharacters.get(CronExRelated._ANY) + " " + year).trim(); */ cronEx = (commons + dayOfMonth + " " + month + " " + CronExRelated.specialCharacters.get(CronExRelated._ANY) + " ").trim(); } System.out.println(cronEx); return cronEx; } }
public class CronExRelated { public static final String _EVERY = "every"; public static final String _ANY = "any"; public static final String _RANGES = "ranges"; public static final String _INCREMENTS = "increments"; public static final String _ADDITIONAL = "additional"; public static final String _LAST = "last"; public static final String _WEEKDAY = "weekday"; public static final String _THENTH = "theNth"; public static final String _CALENDAR = "calendar"; public static final String _TYPE = "type"; /** * 0 0 6 ? * 1#1 ? monthly; 0 0 6 ? * 1 ? weekly; 0 0 6 30 7 ? 2006 useDefined */ static String[] headTitle = { "TYPE", "SECONDS", "MINUTES", "HOURS", "DAYOFMONTH", "MONTH", "DAYOFWEEK", "YEAR" }; /** * cron expression special characters Map specialCharacters */ public static Map specialCharacters; static { specialCharacters = new HashMap(10); specialCharacters.put(_EVERY, "*");// * 代表任意合法的字段 specialCharacters.put(_ANY, "?");// ? 表示没值被指定 ,只能出现在月和星期的字段 specialCharacters.put(_RANGES, "-");// - 表示值的范围 specialCharacters.put(_INCREMENTS, "/");// / 表示时间的增量 specialCharacters.put(_ADDITIONAL, ",");// 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发 specialCharacters.put(_LAST, "L");// L 如果用在"一月哪天"段上,表示一个月的最后一天;如果用在"星期"段上。表示一个星期的最后一天(星期六) specialCharacters.put(_WEEKDAY, "W");// W 表示最靠近给定时间的一天,(必须是星期一到星期五) specialCharacters.put(_THENTH, "#");// 只能出现在"星期"段位置 ,表示第几个星期 specialCharacters.put(_CALENDAR, "C"); specialCharacters.put(_TYPE, headTitle); } public static void set(String ex, int index) { ((String[]) specialCharacters.get(_TYPE))[index] = ex; } }
public class ScheduleInfoManager extends JpaDaoSupport { //把资源表中所有数据载入 public BaseJob queryJobInfo(BaseJob baseJob){ //String sql = "select * from JOB where TriggerName='"+ baseJob.getJob().getTriggerName() +"' and status='P'"; String sql = "select * from JOB where TriggerName='"+ baseJob.getJob().getTriggerName() +"'"; Query query = this.getEntityManager().createNativeQuery(sql,Job.class); //执行查询,返回的是查询的集合 @SuppressWarnings("unchecked") List<Job> jobList = query.getResultList(); baseJob.setJob(jobList.get(0)); System.out.println(jobList.get(0)); return baseJob; } }
/** * 将页面设置的时间转换为Quartz需要的时间格式并启动任务 * * @return */ public String setTaskTime() { // 格式化后quartz的时间 cronExpression = getRuntime(); // 根据id获取job job = jobService.selectByID(Job.class, job.getId()); // 修改job的运行时间 job.setRuntime(cronExpression); // 更新job jobService.update(job); System.out.println("启动任务。。。"); BaseJob baseJob = JobRegistry.getJob(job.getTriggerName()); try { baseJob.reScheduleJob(); } catch (Exception e) { e.printStackTrace(); } System.out.println(cronExpression); return null; }
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean id="scheduleInfoManager" class="cn.com.acca.sas.jobManager.app.service.ScheduleInfoManager"></bean> <bean id="printJob" class="cn.com.acca.sas.jobManager.app.job.PrintJob"> <property name="scheduler" ref="printJobScheduler" /> </bean> <bean id="printJobInvoke" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="printJob"/> <property name="targetMethod" value="reScheduleJob"/> <property name="concurrent" value="false" /> </bean> <bean id="printJobTrigger" class="cn.com.acca.sas.jobManager.app.service.MyCronTrigger"> <property name="job" ref="printJob" /> <property name="jobDetail" ref="printJobInvoke" /> <property name="scheduleInfoManager" ref="scheduleInfoManager"/> </bean> <bean id="printJobScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="printJobTrigger" /> </list> </property> </bean> <!-- 触发器将告诉Quartz两件事:在何时触发任务、触发哪个任务。 cronExpression为调度时间,格式和unix上的crontab类似:"0-5 10,44 14 ? 3 5 2012" 2012年3月某日的星期五14:10和14:44时的1-5秒触发 。其中问号表示忽略该位置(星期)上的值。 jobDetail指向具体的任务调用bean:jobInvoker。如果有多个任务,每个任务的触发时间都不一样,则可以在此配置多个不同的触发器。 --> </beans>
改定时作业只要实现了三种策略: 1.每天xx点执行 2.每周的xx星期xx点执行 3.立即执行