1.引入quartz框架pom依赖
org.quartz-scheduler
quartz
2.3.0
2.创建HelloJob实现Job接口
public class HelloJob implements Job{
private static final SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Date now = new Date();
String currentTime = sdf.format(now);
System.out.println("执行时间为:"+currentTime);
}
}
3.创建HelloScheduler触发任务
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建jobDetail绑定HelloJob
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","myGroup").build();
//创建触发器trigger每个2秒执行一次,一直执行
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "myGroup").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build();
//创建调度者工厂
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
//创建调度者
Scheduler scheduler = schedulerFactory.getScheduler();
//启动调度器
scheduler.start();
//设置调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
}
执行结果:
执行时间为:2019-04-15 23:45:41
23:45:43.388 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.simpl.PropertySettingJobFactory - Producing instance of Job 'myGroup.myJob', class=com.xuxu.quartz.HelloJob
23:45:43.388 [DefaultQuartzScheduler_Worker-9] DEBUG org.quartz.core.JobRunShell - Calling execute on job myGroup.myJob
23:45:43.388 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 1 triggers
执行时间为:2019-04-15 23:45:43
23:45:45.387 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.simpl.PropertySettingJobFactory - Producing instance of Job 'myGroup.myJob', class=com.xuxu.quartz.HelloJob
23:45:45.387 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 1 triggers
23:45:45.391 [DefaultQuartzScheduler_Worker-10] DEBUG org.quartz.core.JobRunShell - Calling execute on job myGroup.myJob
执行时间为:2019-04-15 23:45:45
1同上引入pom依赖
2创建HelloJob实现job接口,任务执行时输出时间
public class HelloJob implements Job{
private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
Date now = new Date();
String currentDate = sdf.format(now);
System.out.println("现在时间是:"+currentDate+":开始执行任务生成表格,或者发送邮件");
}
}
3创建触发类CronScheduler
public class CronScheduler {
public static void main(String[] args) throws Exception {
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob").build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("cronTrigger")
//cron表达式 这里定义的是4月16日早上9点21分开始执行
.withSchedule(CronScheduleBuilder.cronSchedule("0 21 9 16 4 ? *"))
.build();
SchedulerFactory factory = new StdSchedulerFactory();
//创建调度器
Scheduler scheduler = factory.getScheduler();
//启动调度器
scheduler.start();
//jobDetail和trigger加入调度
scheduler.scheduleJob(jobDetail, trigger);
}
}
这里通过cron表达式确定时间规则
一般我们会使用cron生成器,地址是http://cron.qqe2.com/
执行结果如下
现在时间是:2019-04-16 09:21:00:开始执行任务生成表格,或者发送邮件
JobDetail & Job & JobDataMap
JobDetail是任务的定义,而Job是任务的执行逻辑。在JobDetail里会引用一个Job Class定义。每一个JobDetail都会有一个JobDataMap。JobDataMap本质就是一个Map的扩展类,只是提供了一些更便捷的方法,比如getString()之类的。
public class CronScheduler {
public static void main(String[] args) throws Exception {
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
//添加jobname,jobgroup
.withIdentity("myJob","myGroup")
//jobDataMap信息
.usingJobData("message","this is a message")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("cronTrigger")
//cron表达式 这里定义的是4月16日早上9点21分开始执行
.withSchedule(CronScheduleBuilder.cronSchedule("0 00 10 16 4 ? *"))
.build();
SchedulerFactory factory = new StdSchedulerFactory();
//创建调度器
Scheduler scheduler = factory.getScheduler();
//启动调度器
scheduler.start();
//jobDetail和trigger加入调度
scheduler.scheduleJob(jobDetail, trigger);
}
}
public class HelloJob implements Job{
private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Date now = new Date();
String currentDate = sdf.format(now);
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
JobKey jobKey = jobDetail.getKey();
String jobName = jobKey.getName();
String group = jobKey.getGroup();
String message = (String) jobDataMap.get("message");
System.out.println("现在时间是:"+currentDate+":开始执行任务生成表格,或者发送邮件");
System.out.println("jobName---"+jobName);
System.out.println("group---"+group);
System.out.println("message---"+message);
}
}
现在时间是:2019-04-16 10:00:00:开始执行任务生成表格,或者发送邮件
jobName---myJob
group---myGroup
message---this is a message
1.startTime和endTime
有时候我们希望一个定时任务在一定的时间内是每天执行,比如2017年11月24日到2017年12月15日之间执行,这时候我们就要使用startTime和endTime来限定事件范围了。例子中我们把时间规定在几秒钟之内运行,方便查看效果。
public class HelloJob implements Job{
private static final SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Date now = new Date();
String currentTime = sdf.format(now);
System.out.println("执行时间为:"+currentTime);
}
}
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException {
//创建jobDetail绑定HelloJob
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","myGroup").build();
//设定开始时间,结束时间确定范围
Date triggerStartTime = new Date();
//3秒后开始执行
triggerStartTime.setTime(triggerStartTime.getTime()+3000);
Date triggerEndTime = new Date();
//10秒后结束执行
triggerEndTime.setTime(triggerEndTime.getTime()+10000);
//创建触发器trigger每个2秒执行一次,一直执行
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "myGroup")
.startAt(triggerStartTime)
.endAt(triggerEndTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build();
//创建调度者工厂
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
//创建调度者
Scheduler scheduler = schedulerFactory.getScheduler();
//启动调度器
scheduler.start();
//设置调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
}
3秒后执行,10秒内结束执行
如下
执行时间为:2019-04-16 10:36:09
执行时间为:2019-04-16 10:36:11
执行时间为:2019-04-16 10:36:13
执行时间为:2019-04-16 10:36:15
2.BaseCalndar
此calendar不是java.util.Calendar,calendar是为了补充Trigger的时间,可以排除或加入一下特定的时间。Quartz 的 Calender 专门用于屏闭一个时间区间,使 Trigger 在这个区间中不被触发。
这里使用CronCalendar排除
public class HelloJob implements Job{
private static final SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Date now = new Date();
String currentTime = sdf.format(now);
System.out.println("执行时间为:"+currentTime);
}
}
public class HelloScheduler {
public static void main(String[] args) throws SchedulerException, ParseException {
//创建jobDetail绑定HelloJob
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob","myGroup").build();
//创建触发器trigger每个2秒执行一次,一直执行
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("mtTrigger", "myGroup")
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever())
//将calendar排除规则绑定到触发器
.modifiedByCalendar("myCalendar")
.build();
//创建调度者工厂
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
//创建调度者
Scheduler scheduler = schedulerFactory.getScheduler();
CronCalendar calendar = new CronCalendar("* * 0-12,18-23 ? * *");
//向Scheduler注册日历
scheduler.addCalendar("myCalendar", calendar, false, false);
//启动调度器
scheduler.start();
//设置调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
}
11:39:12.270 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 0 triggers
11:39:12.381 [DefaultQuartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 0 triggers
上面指定的是0-12 18-23不执行发现12点之前没有执行
1CalendarIntervalTrigger:是一个具体的Trigger,用来触发基于定时重复的JobDetail。
Trigger将会每隔N个calendar在trigger中定义的时间单元触发一次。这个trigger不适合使用SimpleTrigger完成(例如由于每一个月的时间不是固定的描述),也不适用于CronTrigger(例如每5个月)。
相较于SimpleTrigger有两个优势:1、更方便,比如每隔1小时执行,你不用自己去计算1小时等于多少毫秒。 2、支持不是固定长度的间隔,比如间隔为月和年。但劣势是精度只能到秒。
它适合的任务类似于:9:00 开始执行,并且以后每周 9:00 执行一次
它的属性有:
CalendarIntervalScheduleBuilder
.calendarIntervalSchedule()
.withIntervalInDays(1) //每天执行一次
//.withIntervalInHours(1)
//.withIntervalInMinutes(1)
//.withIntervalInMonths(1)
//.withIntervalInSeconds(1)
//.withIntervalInWeeks(1)
//.withIntervalInHours(1)
.build()
2DailyTimeIntervalTrigger
指定每天的某个时间段内,以一定的时间间隔执行任务。并且它可以支持指定星期。
它适合的任务类似于:指定每天9:00 至 18:00 ,每隔70秒执行一次,并且只要周一至周五执行。
它的属性有:
public static void main(String[] args) throws SchedulerException {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//1.创建一个jobDetail的实例,将该实例与HelloJob Class绑定
JobDetail jobDetail = JobBuilder
.newJob(HelloJob.class)
.withIdentity("myJob", "group1") //定义name 和 group
.build();
//2.创建一个Trigger触发器的实例
Trigger simpleTrigger = TriggerBuilder.newTrigger()
.withIdentity("zhlTrigger")
.withSchedule(
DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule()
.startingDailyAt(TimeOfDay.hourAndMinuteOfDay(8, 0)) //每天8:00开始
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(17, 0)) //17:00 结束
.onDaysOfTheWeek(MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY) //周一至周五执行
.withIntervalInHours(1) //每间隔1小时执行一次
.withRepeatCount(100) //最多重复100次(实际执行100+1次)
)
.modifiedByCalendar("holidays") //将我们设置好的Calander与trigger绑定
.build();
//3.创建schedule实例
StdSchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = factory.getScheduler();
System.out.println("现在的时间 :"+sf.format(new Date()));
System.out.println();
System.out.println("最近的一次执行时间 :"+sf.format(scheduler.scheduleJob(jobDetail,simpleTrigger))); //scheduler与jobDetail、trigger绑定,并打印出最近一次执行的事件
scheduler.start();
}
Scheduler——工厂模式:
所有的Scheduler实例应该由SchedulerFactory来创建,一般包含:StdSchedulerFactory、DirectSchedulerFactory(参数信息需要在代码中维护故不常用)。
StdSchedulerFactory使用一组参数来创建和初始化Quartz调度器,配置参数一般存储在quartz.properties文件中,调用getScheduler方法就能创建和初始化调度器对象。
Scheduler的主要函数:
Data scheduleJob(JobDetail jobDetail,Trigger trigger);
void start();——启动Scheduler;
void standby();——将Scheduler暂时挂起,可以用start()继续执行任务;
void shutDown()关闭Scheduler且不能被重启;示例代码如下: