纯Java开发
二、特点
1.强大的调度功能
Spring默认的调度框架,Quartz可以灵活的与Spring集成,实现灵活的可配置的调度功能,提供调度运行环境的持久化机制,可以保存调度线程,即使系统因故障关闭,任务调度数据并不会丢失,Timer不会做到。2.灵活的运用方式
可灵活的定义触发器的调度事件表,并可以对触发器和任务关联映射,提供了组建式监听器,各种插件,线程池等功能,支持调度数据多种存储方式3.分布式和集群能力
五、重要组成
1.JobschedulerListeger
六、Quartz使用
1.准备工作
建立Maven项目工程引入Quartz jar包
2.编写一个Quartz项目
pom
org.quartz-scheduler
quartz
2.2.3
public class HelloJob implements Job{
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException{
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
//编写具体的业务逻辑
System.out.println("Hello world");
//这里可以获取到执行时候传递的参数
}
}
public class HelloScheduler{
public static void main(String ... args){
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","group1").build();
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒钟执行一次,知道永远
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger","group1")
.startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build();
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
scheduler.scheduleJob(jobDetail,trigger);
}
}
八、浅谈JobDetail
JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。System.out.println("jobDetail,s name:" + jobDetail.getKey().getName());
System.out.println("jobDetail,s group:" + jobDetail.getKey().getGroup());
System.out.println("jobDetail,s jobClass:" + jobDetail.getJobClass().getName());
九、重要属性
//jobDetail中传递两个参数
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob")
.usingJobData("message","hello myJob1").usingJobData("FloatJobValue",3.14F).builder();
//Trigger中传递两个参数
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger","group1")
.usingJobData("message","hello myTrigger1").usingJobData("DoubleTriggerValue",2.0D).
.startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build();
//在HelloJob中获取JobDetail信息
JobKey key = jobExecutionContext.getJobDetail().getKey();
System.out.println("my job name and group are : " = key.getName() + ":" + key.getGroup());
//在HelloJob中获取Trigger信息
TriggerKey trkey = jobExecutionContext.getTrigger().getKey();
System.out.println("my trigger name and group name are :" + trkey.getName() + ":" + trkey.getGroup());
//在HelloJob中获取
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
JobDataMap tjobDataMap = jobExecutionContext.getTrigger().getJobDataMap();
String jobMessage = jobDataMap.getString("mesage");
String jobFloatValue=jobDataMap.getFloat("FloatJobValue");
String jobDoubleValue=jobDataMap.getFloat("DoubleTriggerValue");
其中
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
JobDataMap tjobDataMap = jobExecutionContext.getTrigger().getJobDataMap();
可以修改为
JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
但是注意如果JobDetail和Trigger有同名的key,Trigger会覆盖JobDetail中同名的key
private String message;
private Float FloatJobValue;
private Double DoubleTriggerValue;
//省略getter\setter方法
十二、浅谈Trigger
public class HelloJob implements Job{
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException{
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
Trigger currentTrigger = arg0.getTrigger();
System.out.println("startTime is " + currentTrigger.getStartTime());
System.out.println("endTime is " + currentTrigger.getEndTime());
JobKey jobKey = currentTrigger.getJobKey();
System.out.println("job key info ---" + "jobName:"+jobKey.getName() +"jobGroup:" + jobKey.getGroup());
}
}
public class HelloScheduler{
public static void main(String ... args){
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","group1").build();
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
date.setTime(date.getTime() + 3000);
Date endDate = new Date();
endDate.setTime(date.getTime() + 6000);
//创建一个Trigger实例,获取距离当前时间3秒后的时间
//距离当前时间6秒后停止执行
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger","group1")
.startAt(date).endAt(endDate).withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build();
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
scheduler.scheduleJob(jobDetail,trigger);
}
}
十三、SimpleTrigger
public class HelloJob implements Job{
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException{
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
//编写具体的业务逻辑
System.out.println("Hello world");
}
}
public class HelloScheduler{
public static void main(String ... args){
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","group1").build();
//获取距离4秒钟之后的具体时间
Date date = new Date();
date.setTime(date.getTime()+4000L);
//距离当前时间4秒钟执行,之后每隔两秒钟重复执行一次任务
Date endDate = new Date();
endDate.setTime(endDate.getTime() + 6000L);
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger().withIdentity("myTrigger","group1")
.startAt(date).withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).withRepeatCount(1))
.endAt(endDate).withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatForever()).build();
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
scheduler.scheduleJob(jobDetail,trigger);
}
}
需要注意
public class HelloJob implements Job{
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException{
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
//编写具体的业务逻辑
System.out.println("Hello world");
}
}
public class HelloScheduler{
public static void main(String ... args){
//创建一个JobDetail实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","group1").build();
//每秒钟触发一次任务
//创建一个Trigger实例,定义该Job立即执行,并且每隔两秒钟执行一次,知道永远
CronTrigger trigger = (CronTrigger)TriggerBuilder.newTrigger().withIdentity("myTrigger","group1")
.startNow().withSchedule(CronScheduleBuilder.cronSchedule(* * * * * ?*));
.withIntervalInSeconds(2).repeatForever()).build();
//创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
scheduler.start();
//打印当前的执行时间,格式为2017-02-02 12:00:00
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current Exec Time is " + sf.format(Calender.getTime()));
scheduler.scheduleJob(jobDetail,trigger);
}
}
- 表示 至
* 表示 每
/ 表示 每
?表示 不关心 也可以用*
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 0 12 ? * WED 表示每个星期三中午12点
0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分、18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)
十五、浅谈Scheduler
Scheduler-工厂模式
所有的Scheduler实例应该由SchedulerFactory来创建
SchedulerFactory
StdSchedulerFactory
DirectSchedulerFactory
回顾Quartz三个核心概念
调度器
任务
触发器
Scheduler创建方式
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
DirectSchedulerFactory factory = DirectSchedulerFactory.getInstance();
Scheduler scheduler = factory.getScheduler();
StdSchedulerFactory
使用一组参数(java.util.Properties)来创建和初始化Quartz调度器
配置参数一般存储在quartz.properties中
调用getScheduler方法就能创建和初始化调度器对象
Scheduler主要函数
Date scheduleJob(JobDetail jobDetail,Trigger trigger)
void start()
void standby() scheduler暂时挂起
void shutdown()
十六、quartz.properties
文档的位置和加载顺序
默认加载工程下的quartz.properties文件,如果工程中没有就去读quartz jar包里面的quartz.properties文件里面内容
组成部分
调度器属性
org.quartz.scheduler.instanceName属性用来去区分特定的调度器实例,可以按照功能用途来给调度器起名。
org.quartz.scheduler.instanceId属性和前者一样,也允许任何字符串,单这个值必须是在所有调度器实例中是唯一的,
尤其是在一个集群当中,作为集群的唯一key. 假如你想Quartz帮你生成这个值得话,可以设置为AUTO
线程池属性
threadCount 决定有多少个线程,至少为1,多数机器上值高于100就很不适用了。没有默认值,必须设置值
threadPriority 线程优先级,最大值10 最小值为1,正常值为5(默认值)
org.quartz.treadPool.class
作业存储设置
描述了在调度器实例的生命周期中,Job和Trigger信息是如何存储的
插件配置
满足特定需求用到的Quartz插件配置
十七、使用Quartz配置作业
两种方式
MethodInvokingJobDetailFactoryBean
调用myBean的printMessage方法
MyBean
JobDetailFactoryBean
dispatcher-servlet.xml
text/html;charset=UTF-8
package com.imooc.springquartz.quartz;
import org.springframework.stereotype.Component;
@Component("anotherBean")
public class AnotherBean {
public void printAnotherMessage() {
System.out.println("AnotherMessage");
}
}
package com.imooc.springquartz.quartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.stereotype.Component;
@Component("myBean")
public class MyBean {
public void printMessage() {
// 打印当前的执行时间,格式为2017-01-01 00:00:00
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("MyBean Executes!" + sf.format(date));
}
}
package com.imooc.springquartz.quartz;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class FirstScheduledJob extends QuartzJobBean{
private AnotherBean anotherBean;
public void setAnotherBean(AnotherBean anotherBean){
this.anotherBean = anotherBean;
}
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("FirstScheduledJob Executes!" + sf.format(date));
this.anotherBean.printAnotherMessage();
}
}