quartz入門及通用型自定義定時任務框架
阿新 • • 發佈:2019-01-09
package com.quartz.test; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerKey; import org.quartz.impl.DirectSchedulerFactory; import org.quartz.impl.JobDetailImpl; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.triggers.CronTriggerImpl; import org.quartz.simpl.RAMJobStore; import org.quartz.simpl.SimpleThreadPool; import org.quartz.spi.JobFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.quartz.test.baseJob.JobInfoBean; import com.quartz.test.util.QuartzUtil; public class QuartzManager { static final String KEY_PK = "JobPrimaryKey"; static { // skip quartz update check System.setProperty(StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK, "true"); } private static Logger logger = LoggerFactory.getLogger(QuartzManager.class); private static final String THREAD_NAME_PREFIX = "ThreadPool_%s"; private DirectSchedulerFactory schedulerFactory = DirectSchedulerFactory .getInstance(); private int threadPriority; private String threadNamePrefix; private long misfireThreshold; public int getThreadPriority() { return threadPriority; } public void setThreadPriority(int threadPriority) { this.threadPriority = threadPriority; } public String getThreadNamePrefix() { return threadNamePrefix; } public void setThreadNamePrefix(String threadNamePrefix) { this.threadNamePrefix = threadNamePrefix; } public long getMisfireThreshold() { return misfireThreshold; } public void setMisfireThreshold(long misfireThreshold) { this.misfireThreshold = misfireThreshold; } public DirectSchedulerFactory getSchedulerFactory() { return schedulerFactory; } public void setSchedulerFactory(DirectSchedulerFactory schedulerFactory) { this.schedulerFactory = schedulerFactory; } /** * Schedule jobs * * @param lastestJobList * @throws Exception */ public void scheduleJobs(List<JobInfoBean> lastestJobList) throws Exception { for (JobInfoBean jobInfo : lastestJobList) { this.scheduleJob(jobInfo); } } /** * Schedule jobs with specific JobFactory * * @param lastestJobList * @param jobFactory * @throws Exception */ public void scheduleJobs(List<JobInfoBean> lastestJobList, JobFactory jobFactory) throws Exception { for (JobInfoBean jobInfo : lastestJobList) { this.scheduleJob(jobInfo, jobFactory); } } /** * schedule a job using default JobFacotry * * @param jobInfo * @param rptInfo * @throws Exception */ public void scheduleJob(JobInfoBean jobInfo) throws Exception { this.scheduleJob(jobInfo, null); } /** * schedule a job using custom JobFacotry * * @param jobInfo * @param rptInfo * @param jobFactory * @throws Exception */ public void scheduleJob(JobInfoBean jobInfo, JobFactory jobFactory) throws Exception { Scheduler quartzScheduler = this.getScheduler(jobInfo, jobFactory); if (quartzScheduler.checkExists(new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup()))) { logger.info(String.format("Job [%s] already exists", jobInfo.getJobName())); } else { // Job Details JobDetail job = this.getJobDetail(quartzScheduler, jobInfo); // Cron Trigger Trigger trigger = this.getJobTrigger(quartzScheduler, jobInfo); // Tell quartz to schedule the job using our trigger quartzScheduler.scheduleJob(job, trigger); logger.info(String.format( "Job [%s], Frequency [%s] has been scheduled.", jobInfo.getJobName(), jobInfo.getCronExpression())); } } /** * unSchedule jobs and stop all no job schedulers * * @param lastestJobList * @throws Exception */ public void unscheduleJobs(List<JobInfoBean> lastestJobList) throws Exception { for (JobInfoBean jobInfo : lastestJobList) { this.unScheduleJob(jobInfo); } this.stopAllNoJobScheduler(); } /** * unSchedule a job * * @param jobInfo * @throws Exception */ public void unScheduleJob(JobInfoBean jobInfo) throws Exception { Scheduler quartzScheduler = schedulerFactory.getScheduler(jobInfo .getSchedulerName()); JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup()); if (null == quartzScheduler) { throw new Exception(String.format( "unSchedule Job %s the Scheduler %s does not exists!", jobInfo.getJobName(), jobInfo.getSchedulerName())); } if (quartzScheduler.checkExists(jobKey)) { if (quartzScheduler.deleteJob(jobKey)) { logger.info(String.format("unSchedule Job successfully!\r\n%s", jobInfo.toString())); } else { throw new Exception(String.format( "unSchedule Job failed!\r\n%s", jobInfo.toString())); } } else { logger.warn(String.format("unSchedule Job does not exists!\r\n%s", jobInfo.toString())); } } /** * get scheduler if not exists will create it * * @param jobInfo * @return * @throws SchedulerException */ public Scheduler getScheduler(JobInfoBean jobInfo, JobFactory jobFactory) throws SchedulerException { Scheduler scheduler = schedulerFactory.getScheduler(jobInfo .getSchedulerName()); if (null == scheduler) { this.createScheduler(jobInfo); scheduler = schedulerFactory.getScheduler(jobInfo .getSchedulerName()); // using custom instead of SimpleJobFactory if (null != jobFactory) { scheduler.setJobFactory(jobFactory); } } return scheduler; } /** * create the scheduler * * @param jobInfo * @throws SchedulerException */ private void createScheduler(JobInfoBean jobInfo) throws SchedulerException { String schedulerName = jobInfo.getSchedulerName(); String schedulerInstanceId = jobInfo.getSchedulerName(); SimpleThreadPool threadPool = new SimpleThreadPool( jobInfo.getThreadPoolSize(), threadPriority); this.threadNamePrefix = StringUtils.defaultIfEmpty(threadNamePrefix, THREAD_NAME_PREFIX); threadPool.setThreadNamePrefix(String.format(threadNamePrefix, jobInfo.getSchedulerName())); RAMJobStore jobStore = new RAMJobStore(); jobStore.setMisfireThreshold(misfireThreshold); schedulerFactory.createScheduler(schedulerName, schedulerInstanceId, threadPool, jobStore); } /** * get job details if not exists will create it * * @param quartzScheduler * @param jobInfo * @param plannerInfo * @param rptInfo * @return * @throws Exception */ public JobDetail getJobDetail(Scheduler quartzScheduler, JobInfoBean jobInfo) throws Exception { JobDetail jobDetail = this.getJobDetailFromScheduler(quartzScheduler, jobInfo.getJobName(), jobInfo.getJobGroup()); if (null == jobDetail) { jobDetail = this.createJobDetail(jobInfo); } return jobDetail; } /** * Get JobDetail from Scheduler by job name and job group * * @param scheduler * @param jobName * @param jobGroup * @return * @throws SchedulerException */ public JobDetail getJobDetailFromScheduler(Scheduler scheduler, String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = new JobKey(jobName, jobGroup); return scheduler.getJobDetail(jobKey); } /** * Create a Job Details * * @param jobInfo * @param plannerInfo * @param rptInfo * @return * @throws Exception */ @SuppressWarnings("unchecked") private JobDetail createJobDetail(JobInfoBean jobInfo) throws Exception { JobDetailImpl job = new JobDetailImpl(); job.setJobClass((Class<? extends Job>) Class.forName(jobInfo .getJobClassName())); job.setDescription(null); job.setKey(new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup())); job.setDurability(false); job.setRequestsRecovery(false); JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put(KEY_PK, jobInfo.getPrimaryKey()); job.setJobDataMap(jobDataMap); return job; } /** * if Trigger is created in Scheduler, will return it directly, or create * it. * * @param jobInfo * @return * @throws ParseException * @throws SchedulerException */ public Trigger getJobTrigger(Scheduler quartzScheduler, JobInfoBean jobInfo) throws ParseException, SchedulerException { Trigger trigger = null; TriggerKey triggerKey = new TriggerKey(jobInfo.getTriggerName(), jobInfo.getTriggerGroup()); trigger = quartzScheduler.getTrigger(triggerKey); if (null == trigger) { trigger = this.createTrigger(jobInfo); } return trigger; } /** * create trigger * * @param jobInfo * @return * @throws ParseException */ private Trigger createTrigger(JobInfoBean jobInfo) throws ParseException { CronTriggerImpl trigger = new CronTriggerImpl(); trigger.setTimeZone(QuartzUtil.getTimeZone(jobInfo.getTimeZoneID())); trigger.setName(jobInfo.getTriggerName()); trigger.setGroup(jobInfo.getTriggerGroup()); trigger.setCronExpression(jobInfo.getCronExpression()); return trigger; } /** * Start all Schedulers * * @throws Exception */ public void startAllScheduler() throws Exception { String returnMsg = null; Collection<Scheduler> allScheduler = schedulerFactory .getAllSchedulers(); for (Scheduler scheduler : allScheduler) { returnMsg = this.start(scheduler); logger.info(returnMsg); } } /** * Stop all Schedulers * * @throws Exception */ public void stopAllScheduler() throws Exception { String returnMsg = null; Collection<Scheduler> allScheduler = schedulerFactory .getAllSchedulers(); for (Scheduler scheduler : allScheduler) { returnMsg = this.stop(scheduler); logger.info(returnMsg); } } /** * Pause all Schedulers * * @throws Exception */ public void pauseAllScheduler() throws Exception { String returnMsg = null; Collection<Scheduler> allScheduler = schedulerFactory .getAllSchedulers(); for (Scheduler scheduler : allScheduler) { returnMsg = this.pause(scheduler); logger.info(returnMsg); } } /** * Stop all no job Scheduler * * @throws Exception */ public void stopAllNoJobScheduler() throws Exception { List<Scheduler> needStopSchedulerList = new ArrayList<Scheduler>(); // need stop the scheduler in another List, or will get // ConcurrentModificationException Collection<Scheduler> allScheduler = schedulerFactory .getAllSchedulers(); for (Scheduler scheduler : allScheduler) { if (scheduler.getJobGroupNames().isEmpty()) { needStopSchedulerList.add(scheduler); } } for (Scheduler scheduler : needStopSchedulerList) { this.stop(scheduler); logger.info(String .format("Scheduler %s has been stoped, because it has no any job already.", scheduler.getSchedulerName())); } } /** * Shutdown Scheduler by name * * @param schedName * @throws SchedulerException */ public void shutdownSchedByName(String schedName) throws SchedulerException { schedulerFactory.getScheduler(schedName).shutdown(true); } /** * Stop Scheduler * * @param quartzScheduler * @return * @throws SchedulerException */ public String stop(Scheduler quartzScheduler) throws SchedulerException { String returnMsg = ""; if (!quartzScheduler.isStarted()) { returnMsg = String.format("%s is not started!", quartzScheduler.getSchedulerName()); } else if (quartzScheduler.isShutdown()) { returnMsg = String.format("%s already stoped!", quartzScheduler.getSchedulerName()); } else { // waiting all job complete quartzScheduler.shutdown(true); returnMsg = String.format("Stop %s successfully!", quartzScheduler.getSchedulerName()); } return returnMsg; } /** * Start Scheduler * * @param quartzScheduler * @return * @throws Exception */ public String start(Scheduler quartzScheduler) throws Exception { String returnMsg = ""; if (quartzScheduler.isShutdown()) { quartzScheduler.start(); returnMsg = String.format( "start %s from shutdown status successfully!", quartzScheduler.getSchedulerName()); } else if (quartzScheduler.isStarted() && quartzScheduler.isInStandbyMode()) { quartzScheduler.start(); returnMsg = String.format( "start %s from paused status successfully!", quartzScheduler.getSchedulerName()); } else if (quartzScheduler.isStarted()) { returnMsg = String.format("%s already be started!", quartzScheduler.getSchedulerName()); } else { quartzScheduler.start(); returnMsg = String.format("Start %s successfully!", quartzScheduler.getSchedulerName()); } return returnMsg; } /** * Pause Scheduler * * @param quartzScheduler * @return * @throws SchedulerException */ public String pause(Scheduler quartzScheduler) throws SchedulerException { String returnMsg = ""; if (!quartzScheduler.isStarted()) { returnMsg = String.format( "%s is not started, please start it first!", quartzScheduler.getSchedulerName()); } else if (quartzScheduler.isShutdown()) { returnMsg = String.format("%s is shutdown, please start it first!", quartzScheduler.getSchedulerName()); } else if (quartzScheduler.isInStandbyMode()) { returnMsg = String.format("%s is already be paused!", quartzScheduler.getSchedulerName()); } else { quartzScheduler.standby(); returnMsg = String.format("Paused %s Successfully", quartzScheduler.getSchedulerName()); } return returnMsg; } }