ScanDirectoryJob.java
package org.hzy.quartz;
import java.io.File;
import java.io.FileFilter;
import java.text.ParseException;
import java.util.Date;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
public class ScanDirectoryJob implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
// TODO Auto-generated method stub
JobDetail jdetail = arg0.getJobDetail();
if(jdetail ==null){
throw new RuntimeException("请检查当前作业配置是否完整!");
}
String jobName = jdetail.getName();
System.out.println(jobName + " " + new Date());
JobDataMap jmp = jdetail.getJobDataMap();
String dirName = jmp.getString("SCAN_DIR");
if (dirName == null) {
throw new JobExecutionException("Directory not configured");
}
System.out.println(dirName);
File dir = new File(dirName);
if (!dir.exists()) {
throw new JobExecutionException("Invalid Dir " + dirName);
}
String matchName=jmp.getString("MATCH_NAME");
FileFilter filter = new FileExtensionFileFilter(matchName);
File[] files = dir.listFiles(filter);
int size = files.length;
for (int i = 0; i < size; i++) {
File file = files[i];
File aFile = file.getAbsoluteFile();
long fileSize = file.length();
String msg = aFile + " - Size: " + fileSize;
System.out.println(msg);
}
}
}
当 Quartz 调用 execute() 方法,会传递一个 org.quartz.JobExecutionContext 上下文变量,里面封装有 Quartz 的运行时环境和当前正执行的 Job。通过 JobexecutionContext,你可以访问到调度器的信息,作业和作业上的触发器的信息,还有更多更多的信息。在代码 3.1 中,JobExecutionContext 被用来访问 org.quartz.JobDetail 类,JobDetail 类持有 Job 的详细信息,包括为 Job 实例指定的名称,Job 所属组,Job 是否被持久化(易失性),和许多其他感兴趣的属性。
JobDetail 又持有一个指向 org.quartz.JobDataMap 的引用。JobDataMap 中有为指定 Job 配置的自定义属性。例如,在代码 3.1中,我们从 JobDataMap 中获得欲扫描的目录名,我们可以在 ScanDirectoryJob 中硬编码这个目录名,但是这样的话我们难以重用这个 Job 来扫描别的目录了。在后面有一节“编程方式调度一个 Quartz Job”,你将会看到目录是如何配置到 JobDataMap 的。
execute() 方法中剩下的就是标准 Java 代码了:获得目录名并创建一个 java.io.File 对象。它还对目录名作为简单的校验,确保是一个有效且存在的目录。接着调用 File 对象的 listFiles() 方法得到目录下的文件。还创建了一个 java.io.FileFilter 对象作为参数传递给 listFiles() 方法。org.quartzbook.cavaness.FileExtensionFileFilter 实现了 java.io.FileFilter 接口,它的作用是过滤掉目录仅返回 XML 文件。默认情况下,listFiles() 方法是返回目录中所有内容,不管是文件还是子目录,所以我们必须过滤一下,因为我们只对 XML 文件感兴趣。
注: FileExtensionFileFilter 并非 Quartz 框架的一部分;它是 java.io.FileFilter 的子类,而是 Java 核心的一部分。FileExtensionFileFilter 被创建为我们例子的一部分,用来滤除其他内容而只保留 XML 文件。它相当有用,你可以考虑为你的应用建一系列的文件过滤器,然后在你的 Quartz Job 中重用。 |
FileExtensionFileFilter.java
package org.hzy.quartz;
import java.io.File;
import java.io.FileFilter;
public class FileExtensionFileFilter implements FileFilter {
private String extension;
public FileExtensionFileFilter(String extension) {
this.extension = extension;
}
@Override
public boolean accept(File file) {
// TODO Auto-generated method stub
String lCaseFilename = file.getName().toLowerCase();
return (file.isFile() && (lCaseFilename.indexOf(extension) > 0)) ? true
: false;
}
}
FileExtensionFileFilter 被用来屏蔽名称中不含字符串 “.xml” 的文件。它还屏蔽了子目录--这些子目录原本会让 listFiles() 方法正常返回。过滤器提供了一种很便利的方式选择性的向你的 Quartz 作业提供它能接受的作为输入的文件。
声明式之于编程式配置 在 Quartz 中,我们有两种途径配置应用程序的运行时属性:声明式和编程式。有一些框架是使用外部配置文件的方式;我们都知道,在软件中硬编码设置有它的局限性。 从其他方面来讲,你将要根据具体的需求和功能来选择用哪一种方式。下一节强调了何时用声明式何时选择编程式。因为多数的 Java 行业应用都偏向于声明的方式,这也是我们所推荐的。 |
测试1:
package org.hzy.quartz;
import java.util.Date;
import org.hzy.test.QuartzReport;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
public class Listing_3_6 {
public static void main(String[] args) throws SchedulerException {
Listing_3_6 example = new Listing_3_6();
Scheduler sched = example.createScheduler();
// example.scheduleJob(sched);
sched.start();
example.scheduleJob1(sched, "ScanDirectory1", ScanDirectoryJob.class, "/home/hzy", 10);
example.scheduleJob1(sched, "ScanDirectory2", ScanDirectoryJob.class, "/home/hzy/下载", 15);
// sched.shutdown();
// System.out.println("Scheduler started at " + new Date());
}
public Scheduler createScheduler() throws SchedulerException {
return StdSchedulerFactory.getDefaultScheduler();
}
private void scheduleJob(Scheduler scheduler) throws SchedulerException {
JobDetail jobDetail = new JobDetail("ScanDirectory",
Scheduler.DEFAULT_GROUP, ScanDirectoryJob.class);
jobDetail.getJobDataMap().put("SCAN_DIR", "/home/hzy");
Trigger trigger = TriggerUtils.makeSecondlyTrigger(1);
trigger.setName("scanTrigger");
trigger.setStartTime(new Date());
scheduler.scheduleJob(jobDetail, trigger);
}
private void scheduleJob1(Scheduler scheduler, String jobName,
Class jobClass, String scanDir, int scanInterval)
throws SchedulerException {
JobDetail jobDetail = new JobDetail(jobName, Scheduler.DEFAULT_GROUP,
jobClass);
// jobDetail.getJobDataMap().put("SCAN_DIR", scanDir);
JobDataMap jmp=new JobDataMap();
jmp.put("SCAN_DIR", scanDir);
jmp.put("MATCH_NAME",".xml");
jobDetail.setJobDataMap(jmp);
Trigger trigger = TriggerUtils.makeSecondlyTrigger(scanInterval);
trigger.setName(jobName + "-Trigger");
trigger.setStartTime(new Date());
scheduler.scheduleJob(jobDetail, trigger);
}
}
测试2:
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd" version="1.8">
<schedule>
<job>
<name>ScanDirectory</name>
<group>DEFAULT</group>
<description>
A job that scans a directory for files
</description>
<job-class>
org.hzy.quartz.ScanDirectoryJob
</job-class>
<volatility>false</volatility>
<durability>false</durability>
<recover>false</recover>
<job-data-map>
<entry>
<key>SCAN_DIR</key>
<value>/home/hzy</value>
</entry>
<entry>
<key>MATCH_NAME</key>
<value>.xml</value>
</entry>
</job-data-map>
</job>
<trigger>
<!-- <simple>
<name>scanTrigger</name>
<group>DEFAULT</group>
<job-name>ScanDirectory</job-name>
<job-group>DEFAULT</job-group>
<start-time>2012-07-07T14:42:00</start-time>
<repeat-count>-1</repeat-count>
<repeat-interval>1000</repeat-interval>
</simple>-->
<cron>
<name>scanTrigger</name>
<group>DEFAULT</group>
<job-name>ScanDirectory</job-name>
<job-group>DEFAULT</job-group>
<cron-expression>0/1 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>