写这篇博客的时候是在已经使用了quartz很长之后,我并不是按照从一开始学习的顺序写的,只是记录学了一些我自己的笔记,所以写的很乱,不过读者慢慢看就可以,到最后一定会学的会顺利的。
先到官网上的quick-start上看看,网址http://www.quartz-scheduler.org/overview/quick-start,先声明一下我的学习笔记是关于quartz2.2.x的,这个和2.1.x是不同的。
注意到有个properties file,网站上说这个不是必须的,但是如果要使用的话必须放到classpath下。其实quartz默认已经配置了一个quartz.properties,就在jar包中,先说一下我搭建的学习环境吧,maven的pom如下:
<dependencies> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <exclusions> <exclusion> <!-- 不懂为啥依赖C3P0 --> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> </exclusion> </exclusions> <version>2.2.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.6</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> </dependencies>
然后打开maven dependencies-->quartz-2.2.1.jar -->org.quartz,就可以发现有个quartz.properties了。里面的配置以后再说。(别忘了加入一个log4j.properties在classpath下)
官方文档推荐我们使用自己定义的文件,并且指出,优先使用自己定义的文件,如果没有定义的话才会使用quartz自带的配置文件。这个在源码的这个位置:org.quartz.impl.StdSchedulerFactory.initialize(),如果你也仔细读了这个方法就会知道了,我推荐读一读,对你帮助很大很大。
我们暂时先不加入自己定义的quartz.properties,先做个测试,证明我们的环境是正确的。下面的代码来自于官网,其中有一点改动。
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import job.HelloJob;
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
try {
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
Scheduler sched = schedFact.getScheduler();
//开始调度器
sched.start();
//创建job任务
JobDetail job = newJob(HelloJob.class).withIdentity("myJob", Scheduler.DEFAULT_GROUP).build();
//创建trigger,触发器
Trigger trigger = newTrigger().withIdentity("myTrigger",Scheduler.DEFAULT_GROUP).startNow().withSchedule(simpleSchedule()
.withIntervalInSeconds(3).repeatForever()).build();
//将任务和触发器绑定到调度器
sched.scheduleJob(job, trigger);
System.out.println("执行了");
Thread.sleep(1000000);//这个一定要加上,不然不会有任何输出,原因在最后有解释
sched.shutdown(); //关闭调度器
} catch (SchedulerException se) {
se.printStackTrace();
}
}
}
其中有一些我们平时不常见的写法,比如这里的newJob,newTrigger,都是使用的DSL(Domain-Specific Language) 写法,上面在创建job的时候用到了一个HelloJob.java类,这个类是Job接口的子类,我的代码如下:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("job hello job xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
}
上面的代码的意思是 每个3秒执行一次helloJob的execute方法,我解释一下其中的一些地方:
1、newJob,这个是调用的JobBuiler中的静态方法newJob,目的是创建一个JobBuilder,jobBuilder的方法withIdentity的意思是:使用传入的name和group创建一个jobKey来标示一个工作,可以不同指定group的名字,如果不指定则会自动的创建一个,这在源码中得到体现,我看的源码是:org.quartz.JobBuilder.withIdentity(String)和org.quartz.JobBuilder.withIdentity(String, String)。其实我们完全不用调用withIdentity方法,也就是不用创建一个jobKey,我们可以试着将
.withIdentity("myJob", Scheduler.DEFAULT_GROUP)注释掉,然后执行,也是可以的,但是这样程序会自动的创建一个jobKey,我在源码中看到了,源码是:org.quartz.JobBuilder.build(),在这个方法中会检查jobKey是不是空,如果是的话会创建一个
2、newTrigger,trigger和上面的一样,但是多了一个withSchuduler方法,这个方法是在这个Trigger中创建一个SchedulerBuilder,这里的simpleSchedule()是调用的org.quartz.SimpleScheduleBuilder.simpleSchedule()这个方法,源码很简单,就是创建了一个SImpleSchedulerBuilder,这个类中有三个属性
2.1 interval,表示执行的间隔时间,我们通过withIntervalInSeconds方法设置,单位是秒,
2.2 repeatCount ,一共执行多少次,如果设置为-1,表示无线多次,repeatForever的源码就是这么做的,
2.3 misfireInstruction :这个表示如果misfire后的操作,先不管。
这里我们说的是SimpleSchedulerBuilder,这个类只能做一些简单的定时任务,还有好几个SchudulerBuilder,比如CalendarIntervalScheduleBuilder,CronScheduleBuilder,他们能实现的调度形式更丰富。
在官网上对trigger有如下的说明:
trigger含有一个JobDataMap属性,这个可以用来传送信息,在调用的地方可以通过JobExecutionContext.getTrigger().getJobDataMap()来获得,JobDetail也提供了这个功能。
Quartz提供了两种类型的Tigger,一个是SimpleTigger,一个是CronTrigger。simpleTrigger适用于简单的情况,CronTrigger适用于更复杂的情况,类似于linux中的Crontab指令。
关于trigger还有一点需要注意的是,无论
3、关于identity,来自于官网的解释:group用于将job和trigger分类,比如“reporting job”,“maintenance jobs”。在一个组内,trigger或者是job的名字必须唯一。如果你多看源码的话就会发现,其实name和group组成了一个新的类,job的叫做JobKey,trigger的叫做 TriggerKey,并且在Trigger中也含有对JobKey的引用,trigger对jobkey引用的设置是在这个方法中: org.quartz.core.QuartzScheduler.scheduleJob(JobDetail, Trigger)。
真的写的有点乱。。。。。。。现在对quartz有一个大致的了解了,后面的博客是分成一个个知识点深入讲解的。