1. 程式人生 > >Quartz定時任務排程詳細實現案例

Quartz定時任務排程詳細實現案例

什麼也不說直接上程式碼,程式碼的註釋中有相關的講解。

1、程式碼結構中用到的一些Jar包:

log4j-1.2.16.jar
quartz-2.2.1.jar
quartz-jobs-2.2.1.jar
slf4j-api-1.6.6.jar
slf4j-log4j12-1.6.6.jar

2、獲取Scheduler物件:

package com.pitelin.quartz;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

/**
 * 構建Scheduler工廠
 * @author liZhongLin
 *
 */
public class QuartzSchedulerFactory {

	/**
	 * 定義靜態Scheduler工廠
	 */
	private static SchedulerFactory schedulerFactory;

	/**
	 * 執行靜態程式碼塊
	 */
	static {
		schedulerFactory = new StdSchedulerFactory();
	}

	/**
	 * 返回一個Scheduler物件
	 * @return Scheduler
	 */
	public static Scheduler getInstance() {
		try {
			return QuartzSchedulerFactory.schedulerFactory.getScheduler();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return null;
	}

}

3、獲取CronTrigger物件:

package com.pitelin.quartz;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import org.quartz.CronTrigger;
import com.pitelin.quartz.entity.QuartzParamsEntity;

/**
 * 根據給定的引數,獲取CronTrigger
 * @author liZhongLin
 *
 */
public class QuartzCronTrigger {

	/**
	 * 根據給定的引數,獲取CronTrigger
	 * @param paramsEntity
	 * @return CronTrigger
	 */
	public static CronTrigger getCronTrigger(QuartzParamsEntity paramsEntity) {

		String trigger = paramsEntity.getTriggerName();
		String group = paramsEntity.getGroupName();
		String cronExpression = paramsEntity.getCronExpression();

		return newTrigger().withIdentity(trigger, group).withSchedule(cronSchedule(cronExpression)).build();
	}
}

4、獲取JobDetail物件:

package com.pitelin.quartz;

import static org.quartz.JobBuilder.newJob;

import org.quartz.JobDetail;

import com.pitelin.quartz.entity.QuartzParamsEntity;

/**
 * 根據給定的引數獲取JobDetail物件
 * @author liZhongLin
 *
 */
public class QuartzJobDetail {

	/**
	 * 根據給定的引數獲取JobDetail物件
	 * @param paramsEntity
	 * @return JobDetail
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static JobDetail getJobDetail(QuartzParamsEntity paramsEntity) {
		
		Class jobClass = paramsEntity.getJobClass();
		String jobName = paramsEntity.getJobName();
		String groupName = paramsEntity.getGroupName();

		return newJob(jobClass).withIdentity(jobName, groupName).build();
	}
}

5、啟動和關閉Job執行緒:

package com.pitelin.quartz;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;

import com.pitelin.quartz.entity.QuartzParamsEntity;

/**
 * 
 * 1、Job表示一個工作,要執行的具體內容。此介面中只有一個方法:void execute(JobExecutionContext context)
 * 2、JobDetail表示一個具體的可執行的排程程式,Job是這個可執行程排程程式所要執行的內容,另外JobDetail還包含了這個任務排程的方案和策略。
 * 3、Trigger代表一個排程引數的配置,什麼時候去呼叫。
 * 4、Scheduler代表一個排程容器,一個排程容器中可以註冊多個JobDetail和Trigger。當Trigger與JobDetail組合,就可以被Scheduler容器排程了。
 * 
 * @author liZhongLin
 *
 */
public class QuartzJobStart {

	/**
	 * 定義靜態Scheduler
	 */
	private static Scheduler sched; 
	
	/**
	 * 執行靜態程式碼塊
	 */
	static{
		sched = QuartzSchedulerFactory.getInstance();
	}
	
	/**
	 * Job執行緒啟動操作
	 * @param paramsEntity
	 * @throws SchedulerException
	 */
	public static void start(QuartzParamsEntity paramsEntity) throws SchedulerException { 

        JobDetail job = QuartzJobDetail.getJobDetail(paramsEntity);

		CronTrigger trigger = QuartzCronTrigger.getCronTrigger(paramsEntity);

		sched.scheduleJob(job, trigger);

		sched.start();
	}
	
	/**
	 * Job執行緒關閉操作
	 * @throws SchedulerException
	 */
	public static void stop() throws SchedulerException {
		sched.shutdown(true);
	}
}
6、定義一個Job引數實體:
package com.pitelin.quartz.entity;

/**
 * 定時任務引數實體
 * @author liZhongLin
 *
 */
public class QuartzParamsEntity {

	/**
	 * 執行定時任務的class <? extends Job>
	 */
	private Class<?> jobClass;
	/**
	 * trigger名稱
	 */
	private String triggerName;
	/**
	 * job名稱
	 */
	private String jobName;
	/**
	 * group名稱
	 */
	private String groupName;
	/**
	 * 定時任務表示式
	 */
	private String cronExpression;
		
}

這裡的get和set方法由於篇幅原因,已經刪除,想要執行程式的話,補上就可以了。

7、編寫兩個簡單的Job:

第一個JOB:

package com.pitelin.quartz.job;

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

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 生成一個當前時間的JOB
 * @author liZhongLin
 *
 */
public class DateJob implements Job{
	
	/**
	 * 日誌資訊
	 */
	private final Logger log = LoggerFactory.getLogger(DateJob.class);

	/**
	 * 獲取當前的時間
	 */
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		log.debug("現在的時間為:" + sdf.format(new Date()));
	}
}

第二個JOB:
package com.pitelin.quartz.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 生成一個1-100的隨機數的JOB
 * @author liZhongLin
 *
 */
public class RandomJob implements Job {

	/**
	 * 日誌資訊
	 */
	private final Logger log = LoggerFactory.getLogger(RandomJob.class);
	
	/**
	 * 生成一個1-100的隨機數
	 */
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		int random = (int)(Math.random()*100);
		log.debug("生成的隨機數為:" + random);
	}
}


8、測試Job:

package com.pitelin.quartz.test;

import com.pitelin.quartz.QuartzJobStart;
import com.pitelin.quartz.entity.QuartzParamsEntity;
import com.pitelin.quartz.job.DateJob;
import com.pitelin.quartz.job.RandomJob;

/**
 * 任務排程測試類
 * @author liZhongLin
 *
 */
public class QuartzJobTest {

	/**
	 * 主方法
	 * 這裡的輸入引數使用了硬編碼的方式,最合理的方式是可以把這些引數存放到資料庫當中。
	 * 之後根據查詢的結果賦給List<QuartzParamsEntity>,並迴圈執行任務排程
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {		
		
		QuartzParamsEntity paramsEntityOne = new QuartzParamsEntity();
		paramsEntityOne.setJobClass(DateJob.class);
		paramsEntityOne.setJobName("myJobOne");
		paramsEntityOne.setGroupName("myGroup");
		paramsEntityOne.setTriggerName("myTriggerOne");
		paramsEntityOne.setCronExpression("0/1 * * * * ?");//每個一秒執行一次
		
		QuartzParamsEntity paramsEntityTwo = new QuartzParamsEntity();
		paramsEntityTwo.setJobClass(RandomJob.class);
		paramsEntityTwo.setJobName("myJobTwo");
		paramsEntityTwo.setGroupName("myGroup");
		paramsEntityTwo.setTriggerName("myTriggerTwo");
		paramsEntityTwo.setCronExpression("0/2 * * * * ?");//每個兩秒執行一次
		
		QuartzJobStart.start(paramsEntityOne);
		QuartzJobStart.start(paramsEntityTwo);
		
		Thread.sleep(6000);//執行緒休眠六秒時間
		
		QuartzJobStart.stop();
	}
}

9:、附上log4j.properties資原始檔配置:

log4j.rootLogger =ALL,systemOut

#輸出到控制檯
log4j.appender.systemOut = org.apache.log4j.ConsoleAppender
log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout
log4j.appender.systemOut.layout.ConversionPattern = %-22d{yyyy-MM-dd HH:mm:ss}[%-5p][%l]%m%n
log4j.appender.systemOut.Threshold = DEBUG
log4j.appender.systemOut.ImmediateFlush = TRUE
log4j.appender.systemOut.Target = System.out