https://blog.csdn.net/java_chegnxuyuan/article/details/90205205
在上一篇中我介绍了springboot与quartz的简单的实现以及Job和JobDetail的部分内容。这篇继续介绍Triggers的使用
Triggers具体可以分为SimpleTrigger和CronTrigger。
1.SimpleTrigger:
可以满足的调度需求是,在具体的时间点执行一次,或者在具体的时间点执行,并且以指定的间隔重复执行若干次。比如,你有一个trigger,你可以设置它在2015年1月13日的上午11:23:54准时触发,或者在这个时间点触发,并且每隔2秒触发一次,一共重复5次。
根据描述,你可能已经发现了,SimpleTrigger的属性包括:开始时间、结束时间、重复次数以及重复的间隔。这些属性的含义与你所期望的是一致的,只是关于结束时间有一些地方需要注意。
在上一篇的继续上修改代码如下:会发现第一次执行的时间为2019-05-14 16:07:07,最后一次执行时间为2019-05-14 16:07:57
endTime属性的值会覆盖设置重复次数的属性值;比如,你可以创建一个trigger,在终止时间之前每隔10秒执行一次,你不需要去计算在开始时间和终止时间之间的重复次数,只需要设置终止时间并将重复次数设置为REPEAT_INDEFINITELY(当然,你也可以将重复次数设置为一个很大的值,并保证该值比trigger在终止时间之前实际触发的次数要大即可)。
2.CronTrigger
CronTrigger通常比Simple Trigger更有用,如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。
使用CronTrigger,您可以指定号时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。
即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。
关于corn表达式,可以直接从http://cron.qqe2.com/网站上生产
修改代码如下:
public class TestQuartz {
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 表示一个具体的可执行的调度程序
*/
JobDetail jobDetail = newJob(JobQuartz.class).withIdentity("myJob", "group1")
.usingJobData("jobSays", "Hello World!")
.usingJobData("myFloatValue", 3.141f)
.build();
//定义一个Trigger
/*Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.startNow()
//每个5秒钟执行一次
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5)
//重复执行
.withRepeatCount(5)
).build();*/
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ? *"))//每10秒执行一次
.build();
//创建scheduler
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(jobDetail, cronTrigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
quartz中的TriggerListeners和JobListeners
1.JobListeners
创建JobQuartzListener类,并实现JobListener接口
public class JobQuartzListener implements JobListener {
/**
* 相当于为我们的监听器命名
* @return
*/
@Override
public String getName() {
return "myJobListener";
}
/**
* (1)
* 任务执行之前执行
* @param jobExecutionContext
*/
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
System.out.println("MyJobListener.jobToBeExecuted()");
}
/**
* (2)
* 这个方法正常情况下不执行,但是如果当TriggerListener中的vetoJobExecution方法返回true时,那么执行这个方法
* 需要注意的是 如果方法(2)执行 那么(1),(3)这个俩个方法不会执行,因为任务被终止了嘛.
*/
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
System.out.println("MyJobListener.jobExecutionVetoed()");
}
/**
* (3)
* 任务执行完成后执行,jobException如果它不为空则说明任务在执行过程中出现了异常
* @param jobExecutionContext
* @param e
*/
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
System.out.println("MyJobListener.jobWasExecuted()");
}
}
在scheduler中将自己创建的JobQuartzListener注入进去
需要注意的是,scheduler注入的时候有多种注入方式
1.全局注册,所有Job都会起作用
scheduler.getListenerManager().addJobListener(new JobQuartzListener());
2.指定具体的任务
Matcher<JobKey> matcher = KeyMatcher.keyEquals(new JobKey("job1", "group1"));
sched.getListenerManager().addJobListener(new MyJobListener(), matcher);
3.指定一组任务
GroupMatcher<JobKey> matcher = GroupMatcher.jobGroupEquals("group1");
sched.getListenerManager().addJobListener(new MyJobListener(), matcher);
4.可以根据组的名字匹配开头和结尾或包含
GroupMatcher<JobKey> matcher = GroupMatcher.groupStartsWith("g");
GroupMatcher<JobKey> matcher = GroupMatcher.groupContains("g");
sched.getListenerManager().addJobListener(new MyJobListener(), matcher);
我们这里测试时使用的是第一种方式
2.TriggerListener
创建TriggerQuartzListener类,并实现TriggerListener接口
public class TriggerQuartzListener implements TriggerListener {
@Override
public String getName() {
return "myTriggerListener";
}
/**
* (1)
* Trigger被激发 它关联的job即将被运行
*/
@Override
public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
System.out.println(" Trigger 被触发了,此时Job 上的 execute() 方法将要被执行");
}
/**
* (2)
* Trigger被激发 它关联的job即将被运行,先执行(1),在执行(2) 如果返回TRUE 那么任务job会被终止
*/
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
System.out.println("发现此次Job的相关资源准备存在问题,不便展开任务,返回true表示否决此次任务执行");
return false;//如果这里为true,则任务不会执行
}
/**
* (3) 当Trigger错过被激发时执行,比如当前时间有很多触发器都需要执行,但是线程池中的有效线程都在工作,
* 那么有的触发器就有可能超时,错过这一轮的触发。
*/
@Override
public void triggerMisfired(Trigger trigger) {
System.out.println( "当前Trigger触发错过了");
}
/**
* (4) 任务完成时触发
*/
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
System.out.println("Trigger 被触发并且完成了 Job 的执行,此方法被调用");
}
}
在scheduler中注入TriggerQuartzListener时和job的注入一致。