1,Examples 1 中学到的东西
①在Quartz中,作业的配置与作业具体需要完成什么任务是分开的。作业的配置代码编写在一个类中;如获取调度器:
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
②存储作业的相关属性、数据:
JobDetail jobDetail = newJob(ScanDirectoryJob.class).withIdentity("job1", "group1").build();
jobDetail.getJobDataMap().put(ScanDirectoryJob.SCANDIRECTORY, "F:\\项目技术文档-参考资料\\ohter");
③设置作业的触发条件。可以给同一个作业设置多个触发条件。
SimpleTrigger trigger = (SimpleTrigger)newTrigger().withIdentity("trigger1", "group1")
.startAt(futureDate(10, IntervalUnit.SECOND)).build();
④将作业添加给调度器。可以给同一个Scheduler对象添加多个作业。
Date startDate = sched.scheduleJob(jobDetail, trigger);//throws SchedulerException
⑤启动调度器,开始作业的调度。在这里,作业属性的设置、调度是在main线程上执行的,当作业被调度启动后,Quartz有线程池功能,从线程池中取出线程来执行具体的任务。
sched.start();
⑥最后,作业的任务实现代码编写在另一个类中,这个类需要 implements Job接口,并实现execute()方法,在execute()方法中定义该作业需要实现的具体功能。
下面贴一个定时调度的例子。该调度器在当前时间10s之后去扫描F盘中的doc文件并列出文件的绝对路径和大小。
a):指定扫描的文件类型:
public class FileExtensionsFileFilter implements FileFilter{
private String extensions;
public FileExtensionsFileFilter(String extensions){
this.extensions = extensions;
}
@Override
public boolean accept(File pathname) {
//only accept specified extensions file
String lcaseFileName = pathname.getName().toLowerCase();
return (pathname.isFile() && lcaseFileName.indexOf(extensions) > 0) ? true : false;
}
}b):扫描任务的具体实现
import java.io.File;
import java.io.FileFilter;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.LoggerFactory;
public class ScanDirectoryJob implements Job{
public static final String SCANDIRECTORY = "F:\\项目技术文档-参考资料\\quartz";//默认扫描目录
public static org.slf4j.Logger logger = LoggerFactory.getLogger(ScanDirectoryJob.class);
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String dirDirectory = dataMap.getString(SCANDIRECTORY);//get scan directory from job configuration--JobDataMap
if(dirDirectory == null)
dirDirectory = ScanDirectoryJob.SCANDIRECTORY;
File dir = new File(dirDirectory);
if(!dir.exists() || !dir.isDirectory())
throw new JobExecutionException("Directory does not exist OR It's not a Directory...");
FileFilter filter = new FileExtensionsFileFilter(".doc");
File[] files = dir.listFiles(filter);
if(files == null || files.length == 0){
logger.info("there is no file in directory");
return;
}
logger.info("-----scan file's thread " + Thread.currentThread().getName() + "-----");
int size = files.length;
for(int i = 0; i < size; i++){
File file = files[i];
File aFile = file.getAbsoluteFile();
long fileSize = file.length() / 1024;
logger.info(aFile + " : size " + fileSize + "KB");
}
}
}
c):作业的配置、设置触发条件、启动作业
import static org.quartz.DateBuilder.futureDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
public class ScanDirectoryJobExample {
public void run() throws Exception{
Logger log = LoggerFactory.getLogger(ScanDirectoryJobExample.class);
log.info("--------initialzing--------");
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info("-------initialzation completed-------");
JobDetail jobDetail = newJob(ScanDirectoryJob.class).withIdentity("job1", "group1").build();
SimpleTrigger trigger = (SimpleTrigger)newTrigger().withIdentity("trigger1", "group1")
.startAt(futureDate(10, IntervalUnit.SECOND)).build();
jobDetail.getJobDataMap().put(ScanDirectoryJob.SCANDIRECTORY, "F:\\项目技术文档-参考资料\\ohter");
Date startDate = sched.scheduleJob(jobDetail, trigger);//throws SchedulerException
log.info("-----" + jobDetail.getKey() + " will run at " + startDate + " and repeat " + trigger.getRepeatCount()
+ " times, every " + trigger.getRepeatInterval() / 1000 + " seconds. -----");
log.info("------- Starting Scheduler ----------------");
sched.start();
/*
* 在这里必须让主线程sleep一段时间,这样让工作线程有足够的时间运行完从而查看执行结果。
* 不然,主线程后紧接着执行 sched.shutdown(),会使得任务还未执行完成就已经将调度器关闭了
*/
try{
log.info("------Thread Name " + Thread.currentThread().getName() + "------");
Thread.sleep(60L * 1000);//wait 60s to show result
}catch(Exception e){}
log.info("-------shutting down -------");
sched.shutdown();
log.info("-------shutdown completed-------");
//display some stats about the scheduler that just run
SchedulerMetaData metaData = sched.getMetaData();
log.info("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception{
ScanDirectoryJobExample scanDirectory = new ScanDirectoryJobExample();
scanDirectory.run();
}
}
本文介绍了开源作业调度软件Quartz2.2.2的学习,重点讲解了Examples 1中的关键点,包括作业配置与任务实现的分离,如何设置作业属性、触发条件,如何添加作业到调度器,以及启动调度器后的线程池工作原理。同时,给出了一个定时扫描F盘doc文件并显示文件信息的实例。

1245

被折叠的 条评论
为什么被折叠?



