我们新建好一个maven工程之后,到quartz的官网中找到想要的版本,此处用的是2.2.3,然后引入依赖 。
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
然后新建两个类,一个HelloJob类实现Job接口中的execute方法,编写具体的业务逻辑。
还有一个HelloSchedule类,创建JobDetail实例,引入HelloJob类文件,然后创建trigger实例,定义job完成的方式(次数,时间等。)
HelloJob类:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//编写具体的业务逻辑
Date date=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yy-mm-dd HH:mm:ss");
System.out.println("Current execu time is "+sf.format(date));
System.out.println("Hello world!");
}
}
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HelloSchedule {
public static void main(String[] args) throws SchedulerException{
//创建一个JobDetail实例,引入该实例
JobDetail jobDetail= JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","group1").build();
//创建一个Trigger实例,定义该job立即执行,每隔两秒钟重复执行一次
//这里我们把trigger和jobDetail定在同一组,其实不是同一组的
Trigger trigger= TriggerBuilder.newTrigger()
.withIdentity("myTrigger","group1")
.startNow()
.withSchedule(SimpleScheduleBuilder//SimpleScheduleBuilder是简单调用触发器,它只能指定触发的间隔时间和执行次数;
.simpleSchedule()//创建一个SimpleScheduleBuilder
.withIntervalInSeconds(20)//指定一个重复间隔,以秒为单位。
.withRepeatCount(10))//指定反复的次数
.build();//注意build是的主语是谁
//创建trigger实例
SchedulerFactory sf=new StdSchedulerFactory();
Scheduler scheduler=sf.getScheduler();
scheduler.start();
//打印当前时间
Date date=new Date();
SimpleDateFormat sf1=new SimpleDateFormat("yy-mm-dd HH:mm:ss");
System.out.println("Current time is "+sf1.format(date));
scheduler.scheduleJob(jobDetail,trigger);
}
}
实现效果如图:
JobDataMap:
在进行任务调度的时候JobDataMap存储在JobExecutionContext中,非常方便获取。
JobExecutionContext是实现Job类的execute方法的参数。
JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。
他实现了jdk的Map接口,并且添加了一些方法方便的用来存取基本数据类型。
获取jobdataMap的方式1:从Map中获取。
再来看看实例,我们在HelloSchedule中定义一个JobDataMap,实现一些信息:
然后就可以在HelloJob中获取到我们自定义的信息。
//然后还可以获取到我们自定义的JobDataMap中的信息
JobDataMap jobDataMap=jobExecutionContext.getJobDetail().getJobDataMap();
JobDataMap triggerDataMap=jobExecutionContext.getTrigger().getJobDataMap();
String jobMsg=jobDataMap.getString("message");
Float floatJobValue=jobDataMap.getFloatValue("FloatJobValue");
String triggerMsg=triggerDataMap.getString("message");
Double doubleTriggerValue=triggerDataMap.getDoubleValue("DoubleTriggerValue");
还有第二种方式,直接使用getMergedJobDataMap:
//然后还可以获取到我们自定义的JobDataMap中的信息
JobDataMap dataMap=jobExecutionContext.getMergedJobDataMap();
String msg=dataMap.getString("message");//此时会优先打印出 trigger的message
Float floatJobValue=dataMap.getFloatValue("FloatJobValue");
// String triggerMsg=dataMap.getString("message");
Double doubleTriggerValue=dataMap.getDoubleValue("DoubleTriggerValue");
System.out.println("Msg is "+msg);
System.out.println("Job:floatJobValue is "+floatJobValue);
System.out.println("Trigger:doubleTriggerValue is "+doubleTriggerValue);
获取jobdataMap的方式2:Job的实现类中使用setter方法对应JobDataMap的键值。
注意:Quartz框架默认的JobFactory实现类在初始化job实例对象的时候会自动调用setter方法。
在本例子中,其实就是在HelloJob中直接定义所需的变量,注意变量名称要和HelloSchedule中定义的useJobDataMap的值一样,实现get set方法,就可以直接获取到变量值,并且打印。
只要保证变量名字和HelloSchedule中传入的参数name一致,就可以直接打印:
运行效果截图:
Trigger:
Trigger的通过性:
Jobkey:表示job实例的标识,触发器被触发时,该指定的Job实例会执行。
StartTime:首次被触发的时间
Endtime:不再被执行的时间啊。
这些比较简单,直接上代码:
HelloScheduler中定义Trigger的StartTime和EndTIme以及JobKey,然后在HelloJob中获取并打印;
运行效果如下:
SimpleTrigger:
SimpleTrigger:在一个指定时间内执行一次任务或者在指定的一个时间间隔内多次执行任务。
我们实现了一个简单的例子用于SimpleTrigger的学习:
//注意:EndTime优先于RepeatCount,并且RepeatCount可以是0 正整数以及SimpleTrigger.REPEAT_INDEFINITELY常量值。
Date triggerStartTime=new Date();
triggerStartTime.setTime(triggerStartTime.getTime()+4000);
Date triggerEndTime= new Date();
triggerEndTime.setTime(triggerStartTime.getTime()+8000);
SimpleTrigger trigger= (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity("myTrigger","group1")
.startAt(triggerStartTime)
.withSchedule(SimpleScheduleBuilder
.simpleSchedule()
.withIntervalInSeconds(5)
.withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)//循环无数次
)
.build();
CronTrigger
基于日历的时间触发器,没有SimpleTrigger精确,比SimpleTrigger更常用,因为可以覆盖SimpleTrigger。
使用Cron表达式:
这里的#表示的第的意思;6表示星期五。
Cron表达式中:
L和W可以一起使用:一个月的最后工作日触发:在日字段上用LW表示;
周字段的英文字母不区分大小写;然后是cron表达式的在线生成:http://cron.qqe2.com/
Schedule
我们主要学习的是StdSchedulerFactory,
Scheduler的主要函数:
Date scheduleJob(JobDetail jobDetail,Trigger trigger);
void start();
void standby();//暂定scheduler当前的工作,挂起状态
Scheduler有一个shutdown方法,shutDown之后不能再启动。另外,shutDown是有参数的,如果参数为true,那么表示等待所有正在执行的job执行完毕之后再关闭scheduler,若为false,表示直接关闭scheduler。
Spring Quartz
Spring中引入Quartz的包:
需要一些spring相关的依赖:然后再引入quartz
在SpringMVC中使用Quartz,有两种配置方式,MethodInvokingJobDetailFactoryBean以及JobDetailFactoryBean。
首先,第一种方式:
其中FirstScheduledJob类继承自QuartzJobBean
建好类之后,另外需要在dispatcher-servlet.xml文件中配置bean,两个JobDetail
最后将两个JobDetail和两个trigger引入:
然后在myBean中加入一些时间的输出:
同样的在FirstScheduleJob中也加入时间的输出。
需要注意的是:需要加上下面这句话,否则会报错
<property name="Durability" value="true"/>
运行效果截图: