Quartz监听器(详解)---Listerner

Quartz的监听器用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知。类似于任务执行过程中的邮件、短信类的提醒。Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种,分别表示任务、触发器、调度器对应的监听器。三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,二者的区别在于:全局监听器能够接收到所有的Job/Trigger的事件通知,而非全局监听器只能接收到在其上注册的Job或Trigger的事件,不在其上注册的Job或Trigger则不会进行监听。

一、TriggerListener

跟触发器有关的事件包括:触发器被触发,触发器触发失败,以及触发器触发完成(触发器完成后作业任务开始运行)。

TriggerListener 接口源码
public interface ITriggerListener
{
     string Name { get; }

     void TriggerFired(ITrigger trigger, IJobExecutionContext context);

     bool VetoJobExecution(ITrigger trigger, IJobExecutionContext context);

     void TriggerMisfired(ITrigger trigger);

     void TriggerComplete(ITrigger trigger, IJobExecutionContext context, int triggerInstructionCode);
}

含义:

  1. 1getName方法:用于获取触发器的名称
  2. triggerFired方法:当与监听器相关联的Trigger被触发,Job上的execute()方法将被执行时,Scheduler就调用该方法。
  3. vetoJobExecution方法:在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。
  4.  triggerMisfired方法:Scheduler 调用这个方法是在 Trigger 错过触发时。你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。
  5.  triggerComplete方法:Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。

使用:

  1. 创建一个监听器,实现org.quartz.TriggerListener或org.quartz.JobListener接口的对象即可。监听器会在运行期间注册到调度器中,并且必须要给定监听器名(更确切地说,监听器会调用getName方法获取自己的名字)。
  2.  监听器注册到调度器中的监听器管理类时还携带着一个匹配器,这个匹配器描述了作业任务和触发器的监听器想接收的事件。
  3.  监听器在运行期间注册到调度中,但是不会把作业任务和触发器存储到JobStore中。那是因为监听器在你的应用中通常是一些点的集合。因此,每次应用运行时,监听器都需要重新在调度器中注册。

 示例:

TimerJob类:

package com.ghuiqun.timer;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.gzhuiqun.listener.TimerJobListener;


/*
 * 
 * 定义需要执行的任务。该类是一个接口,只定义一个方法 execute(JobExecutionContext context)
	在实现类的 execute 方法中编写所需要定时执行的 Job(任务), JobExecutionContext 类提供了调度应用的一些信息。
	Job 运行时的信息保存在 JobDataMap 实例中。
 */
public class TimerJob implements Job {

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		Logger logger = Logger.getLogger(TimerJobListener.class);
		logger.info("坚持 坚持  在坚持,永不放弃"+ new Date());
		System.out.println("坚持 坚持  在坚持,永不放弃"+ new Date());
	}

}

TimerTriggerListerner类:

package com.gzhuiqun.listener;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.Trigger.CompletedExecutionInstruction;
import org.quartz.TriggerListener;
/**
 * @author Administrator
 * 跟触发器有关的事件包括:触发器被触发,触发器触发失败,以及触发器触发完成(触发器完成后作业任务开始运行)。
 */
public class TimerTriggerListener implements TriggerListener{
	Logger logger = Logger.getLogger(TimerTriggerListener.class);
	private String timerTriggerName="";
	
	public TimerTriggerListener(String timerTriggerName) {
		this.timerTriggerName = timerTriggerName;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		logger.info(timerTriggerName);
		System.out.println(timerTriggerName);
		return timerTriggerName;
	}
	
	//触发器触发完成
	//(4) 任务完成时触发
	@Override
	public void triggerComplete(Trigger arg0, JobExecutionContext arg1, CompletedExecutionInstruction arg2) {
		// TODO Auto-generated method stub
		logger.info("触发器触发完成");
		System.out.println("触发器触发完成");
	}
	//触发器被触发
	//(1)Trigger被激发 它关联的job即将被运行
	@Override
	public void triggerFired(Trigger arg0, JobExecutionContext arg1) {
		// TODO Auto-generated method stub
		logger.info("Trigger被激发 它关联的job即将被运行");
		System.out.println("触发器被触发");
	}
	//触发器触发失败
	//(3) 当Trigger错过被激发时执行,比如当前时间有很多触发器都需要执行,但是线程池中的有效线程都在工作,
	//那么有的触发器就有可能超时,错过这一轮的触发。
	@Override
	public void triggerMisfired(Trigger arg0) {
		// TODO Auto-generated method stub
		logger.info("触发器触发失败");
		System.out.println("触发器触发失败");
	}
	//(2)Trigger被激发 它关联的job即将被运行,先执行(1),在执行(2) 如果返回TRUE 那么任务job会被终止
	@Override
	public boolean vetoJobExecution(Trigger arg0, JobExecutionContext arg1) {
		// TODO Auto-generated method stub
		return false;
	}

}

任务调度与运行,及TriggerListener的创建与注册。

package com.ghuiqun.timer;

import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;

import com.gzhuiqun.listener.TimerJobListener;
import com.gzhuiqun.listener.TimerSchedulerListener;
import com.gzhuiqun.listener.TimerTriggerListener;

public class TimerExample {
	// 创建 schedulerFactory 工厂
	private static SchedulerFactory scheduleFactory= new StdSchedulerFactory();
	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] data= {"s","t","r","i","n","g"};
		addJob("HelloJob","HelloJobGroup","HelloTrigger","HelloTriggerGroup",TimerJob.class,"0/1 * * * * ?",data);
	}
	/**添加一个定时任务
	 * @param jobName 任务名
	 * @param jobGroupName 任务组名
	 * @param triggerName 触发器名
	 * @param triggerGroupName 触发器组名
	 * @param jobClass 任务类名
	 * @param cron 时间
	 */
	public static void addJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName
			,Class<? extends Job> jobClass,String cron,String[] data) {
		try {
			//通过scheduleFactory创建任务调度器
			Scheduler scheduler = scheduleFactory.getScheduler();
			
			//创建 jobDetail 实例,绑定 Job 实现类
			// 指明 job 的名称,所在组的名称,以及绑定 job 类
			JobDetail job = (JobDetail) JobBuilder.newJob(jobClass)
					.withIdentity(jobName,jobGroupName)
					//.requestRecovery() // 执行中应用发生故障,需要重新执行
					.build();
					// 初始化参数传递到 job
					job.getJobDataMap().put("data",data);
					
			// 定义调度触发规则CronTrigger
			//指明 CronTrigger 的名称,所在组的名称,触发时间
			Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
					.withIdentity(triggerName,triggerGroupName)
					.startNow()
					.withSchedule(CronScheduleBuilder.cronSchedule(cron))
					.build();
			
			// 把作业和触发器注册到任务调度中
			scheduler.scheduleJob(job,trigger);
			// 创建并注册一个全局的TriggerListener
	        scheduler.getListenerManager().addTriggerListener(new TimerTriggerListener("TimerTrigger"), EverythingMatcher.allTriggers());
	        // 创建并注册一个局部的TriggerListener
//	        scheduler.getListenerManager().addTriggerListener(new TimerTriggerListener("TimerTrigger"), KeyMatcher.keyEquals(TriggerKey.triggerKey(triggerName, triggerGroupName)));
	        // 创建并注册一个特定组的TriggerListener
//	        scheduler.getListenerManager().addTriggerListener(new TimerTriggerListener("TimerTrigger"), GroupMatcher.groupEquals(triggerGroupName));
			
			//启动
			if(!scheduler.isShutdown()) {
				scheduler.start();
				System.out.println("开始调度任务");
			}
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

结果:

2019-04-03 10:16:53  [ main:592 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ main:592 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ main:592 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ main:592 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ main:607 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ main:607 ] - [ INFO ]  触发器触发失败
2019-04-03 10:16:53  [ main:629 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ main:629 ] - [ INFO ]  触发器触发失败
2019-04-03 10:16:53  [ MyScheduler_Worker-1:708 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-1:709 ] - [ INFO ]  Trigger被激发 它关联的job即将被运行
2019-04-03 10:16:53  [ MyScheduler_Worker-1:711 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:16:53 CST 2019
2019-04-03 10:16:53  [ MyScheduler_Worker-1:711 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-1:712 ] - [ INFO ]  触发器触发完成
2019-04-03 10:16:53  [ MyScheduler_Worker-2:814 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-2:814 ] - [ INFO ]  Trigger被激发 它关联的job即将被运行
2019-04-03 10:16:53  [ MyScheduler_Worker-2:815 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:16:53 CST 2019
2019-04-03 10:16:53  [ MyScheduler_Worker-2:815 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-2:815 ] - [ INFO ]  触发器触发完成
2019-04-03 10:16:53  [ MyScheduler_Worker-3:878 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-3:878 ] - [ INFO ]  Trigger被激发 它关联的job即将被运行
2019-04-03 10:16:53  [ MyScheduler_Worker-3:878 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:16:53 CST 2019
2019-04-03 10:16:53  [ MyScheduler_Worker-3:879 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-3:879 ] - [ INFO ]  触发器触发完成
2019-04-03 10:16:53  [ MyScheduler_Worker-4:905 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-4:905 ] - [ INFO ]  Trigger被激发 它关联的job即将被运行
2019-04-03 10:16:53  [ MyScheduler_Worker-4:905 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:16:53 CST 2019
2019-04-03 10:16:53  [ MyScheduler_Worker-4:905 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:53  [ MyScheduler_Worker-4:905 ] - [ INFO ]  触发器触发完成
2019-04-03 10:16:54  [ MyScheduler_Worker-5:1470 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:54  [ MyScheduler_Worker-5:1470 ] - [ INFO ]  Trigger被激发 它关联的job即将被运行
2019-04-03 10:16:54  [ MyScheduler_Worker-5:1470 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:16:54 CST 2019
2019-04-03 10:16:54  [ MyScheduler_Worker-5:1471 ] - [ INFO ]  TimerTrigger
2019-04-03 10:16:54  [ MyScheduler_Worker-5:1471 ] - [ INFO ]  触发器触发完成

二、JobListener

跟任务相关的事件包括:job开始要执行的提示; job执行完成的提示灯

JobListener接口源码
public interface JobListener {

    public String getName();

    public void jobToBeExecuted(JobExecutionContext context);

    public void jobExecutionVetoed(JobExecutionContext context);

    public void jobWasExecuted(JobExecutionContext context,
            JobExecutionException jobException);

}

含义:

  1.  getName方法:用于获取该JobListener的名称。
  2.  jobToBeExecuted方法:Scheduler在JobDetail将要被执行时调用这个方法。
  3.  jobExecutionVetoed方法:Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法
  4. jobWasExecuted方法:Scheduler在JobDetail被执行之后调用这个方法

 示例:

TimerJob类:

package com.ghuiqun.timer;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.gzhuiqun.listener.TimerJobListener;


/*
 * 
 * 定义需要执行的任务。该类是一个接口,只定义一个方法 execute(JobExecutionContext context)
	在实现类的 execute 方法中编写所需要定时执行的 Job(任务), JobExecutionContext 类提供了调度应用的一些信息。
	Job 运行时的信息保存在 JobDataMap 实例中。
 */
public class TimerJob implements Job {

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		Logger logger = Logger.getLogger(TimerJobListener.class);
		logger.info("坚持 坚持  在坚持,永不放弃"+ new Date());
		System.out.println("坚持 坚持  在坚持,永不放弃"+ new Date());
	}

}

TimerJobListener类:

package com.gzhuiqun.listener;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
/**
 * @author Administrator
 *	 跟作业任务相关的事件包括:job即将被执行的通知和job执行完成的通知事件。
 */
public class TimerJobListener implements JobListener {
	Logger logger = Logger.getLogger(TimerJobListener.class);
	//获取该JobListener的名称
	@Override
	public String getName() {
		// TODO Auto-generated method stub
		 String name = getClass().getSimpleName();
		logger.info(name);
		return name;
	}
	//:Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法
	@Override
	public void jobExecutionVetoed(JobExecutionContext arg0) {
		// TODO Auto-generated method stub
		logger.info("Scheduler在JobDetail即将被执行,但又被TriggerListerner否决");
		System.out.println("jobExecutionVetoed");
	}
	//Scheduler在JobDetail将要被执行时调用这个方法。
	@Override
	public void jobToBeExecuted(JobExecutionContext arg0) {
		// TODO Auto-generated method stub
		logger.info("Scheduler在JobDetail将要被执行");
		System.out.println("jobToBeExecuted");
	}
	//Scheduler在JobDetail被执行之后调用这个方法
	@Override
	public void jobWasExecuted(JobExecutionContext arg0, JobExecutionException arg1) {
		// TODO Auto-generated method stub
		logger.info("Scheduler在JobDetail被执行之后");
		System.out.println("jobWasExecuted");
	}

}

任务调度与运行,及TimerJobListener的创建与注册。

package com.ghuiqun.timer;

import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;

import com.gzhuiqun.listener.TimerJobListener;
import com.gzhuiqun.listener.TimerSchedulerListener;
import com.gzhuiqun.listener.TimerTriggerListener;

public class TimerExample {
	// 创建 schedulerFactory 工厂
	private static SchedulerFactory scheduleFactory= new StdSchedulerFactory();
	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] data= {"s","t","r","i","n","g"};
		addJob("HelloJob1","HelloJobGroup","HelloTrigger1","HelloTriggerGroup",TimerJob.class,"0/1 * * * * ?",data);
	}
	/**添加一个定时任务
	 * @param jobName 任务名
	 * @param jobGroupName 任务组名
	 * @param triggerName 触发器名
	 * @param triggerGroupName 触发器组名
	 * @param jobClass 任务类名
	 * @param cron 时间
	 */
	public static void addJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName
			,Class<? extends Job> jobClass,String cron,String[] data) {
		try {
			//通过scheduleFactory创建任务调度器
			Scheduler scheduler = scheduleFactory.getScheduler();
			
			//创建 jobDetail 实例,绑定 Job 实现类
			// 指明 job 的名称,所在组的名称,以及绑定 job 类
			JobDetail job = (JobDetail) JobBuilder.newJob(jobClass)
					.withIdentity(jobName,jobGroupName)
					//.requestRecovery() // 执行中应用发生故障,需要重新执行
					.build();
					// 初始化参数传递到 job
					job.getJobDataMap().put("data",data);
					
			// 定义调度触发规则CronTrigger
			//指明 CronTrigger 的名称,所在组的名称,触发时间
			Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
					.withIdentity(triggerName,triggerGroupName)
					.startNow()
					.withSchedule(CronScheduleBuilder.cronSchedule(cron))
					.build();
			
			// 把作业和触发器注册到任务调度中
			scheduler.scheduleJob(job,trigger);
	
			
			// 创建并注册一个全局的Job Listener
	        scheduler.getListenerManager().addJobListener(new TimerJobListener(), EverythingMatcher.allJobs());
	        // 创建并注册一个指定任务的Job Listener
//	        scheduler.getListenerManager().addJobListener(new TimerJobListener(), KeyMatcher.keyEquals(JobKey.jobKey(jobName,jobGroupName)));
			
			//启动
			if(!scheduler.isShutdown()) {
				scheduler.start();
				System.out.println("开始调度任务");
			}
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

结果:

2019-04-03 10:13:53  [ main:529 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ main:529 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ main:529 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ main:529 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ MyScheduler_Worker-1:625 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ MyScheduler_Worker-1:625 ] - [ INFO ]  Scheduler在JobDetail将要被执行
2019-04-03 10:13:53  [ MyScheduler_Worker-1:628 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:13:53 CST 2019
2019-04-03 10:13:53  [ MyScheduler_Worker-1:628 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ MyScheduler_Worker-1:628 ] - [ INFO ]  Scheduler在JobDetail被执行之后
2019-04-03 10:13:53  [ MyScheduler_Worker-2:647 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ MyScheduler_Worker-2:647 ] - [ INFO ]  Scheduler在JobDetail将要被执行
2019-04-03 10:13:53  [ MyScheduler_Worker-2:648 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:13:53 CST 2019
2019-04-03 10:13:53  [ MyScheduler_Worker-2:648 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:53  [ MyScheduler_Worker-2:648 ] - [ INFO ]  Scheduler在JobDetail被执行之后
2019-04-03 10:13:54  [ MyScheduler_Worker-3:1094 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:54  [ MyScheduler_Worker-3:1094 ] - [ INFO ]  Scheduler在JobDetail将要被执行
2019-04-03 10:13:54  [ MyScheduler_Worker-3:1094 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:13:54 CST 2019
2019-04-03 10:13:54  [ MyScheduler_Worker-3:1095 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:54  [ MyScheduler_Worker-3:1095 ] - [ INFO ]  Scheduler在JobDetail被执行之后
2019-04-03 10:13:55  [ MyScheduler_Worker-4:2101 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:55  [ MyScheduler_Worker-4:2102 ] - [ INFO ]  Scheduler在JobDetail将要被执行
2019-04-03 10:13:55  [ MyScheduler_Worker-4:2102 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 10:13:55 CST 2019
2019-04-03 10:13:55  [ MyScheduler_Worker-4:2103 ] - [ INFO ]  TimerJobListener
2019-04-03 10:13:55  [ MyScheduler_Worker-4:2103 ] - [ INFO ]  Scheduler在JobDetail被执行之后

备注:

除了代码中将对应的job注册到监听器中的两种方法,也有如下几种其他方法:

1) 将同一任务组的任务注册到监听器中

scheduler.getListenerManager().addJobListener(new TimerJobListener(), GroupMatcher.jobGroupEquals(jobGroupName));

2) 将两个任务组的任务注册到监听器中

scheduler.getListenerManager().addJobListener(new TimerJobListener(), OrMatcher.or(GroupMatcher.jobGroupEquals(jobGroupName), GroupMatcher.jobGroupEquals(jobGroupName)));

三、SchedulerListener

SchedulerListener会在Scheduler的生命周期中关键事件发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger,删除一个job/trigger,scheduler发生严重错误,关闭scheduler等

SchedulerListener接口源码
public interface SchedulerListener {

    public void jobScheduled(Trigger trigger);

    public void jobUnscheduled(String triggerName, String triggerGroup);

    public void triggerFinalized(Trigger trigger);

    public void triggersPaused(String triggerName, String triggerGroup);

    public void triggersResumed(String triggerName, String triggerGroup);

    public void jobsPaused(String jobName, String jobGroup);

    public void jobsResumed(String jobName, String jobGroup);

    public void schedulerError(String msg, SchedulerException cause);

    public void schedulerStarted();

    public void schedulerInStandbyMode();

    public void schedulerShutdown();

    public void schedulingDataCleared();
}

含义:

  1.  jobScheduled方法:用于部署JobDetail时调用
  2.  jobUnscheduled方法:用于卸载JobDetail时调用
  3.  triggerFinalized方法:当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。
  4. triggersPaused方法:Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。
  5.  triggersResumed方法:Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null。参数将为 null。
  6. jobsPaused方法:当一个或一组 JobDetail 暂停时调用这个方法。
  7. jobsResumed方法:当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。
  8. schedulerError方法:在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。
  9.  schedulerStarted方法:当Scheduler 开启时,调用该方法
  10.  schedulerInStandbyMode方法: 当Scheduler处于StandBy模式时,调用该方法
  11.  schedulerShutdown方法:当Scheduler停止时,调用该方法
  12. schedulingDataCleared方法:当Scheduler中的数据被清除时,调用该方法。

 示例:

TimerJob类:

package com.ghuiqun.timer;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.gzhuiqun.listener.TimerJobListener;


/*
 * 
 * 定义需要执行的任务。该类是一个接口,只定义一个方法 execute(JobExecutionContext context)
	在实现类的 execute 方法中编写所需要定时执行的 Job(任务), JobExecutionContext 类提供了调度应用的一些信息。
	Job 运行时的信息保存在 JobDataMap 实例中。
 */
public class TimerJob implements Job {

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		Logger logger = Logger.getLogger(TimerJobListener.class);
		logger.info("坚持 坚持  在坚持,永不放弃"+ new Date());
		System.out.println("坚持 坚持  在坚持,永不放弃"+ new Date());
	}

}

TimerSchedulerListener类:

package com.gzhuiqun.listener;

import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.ScheduleBuilder;
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
/**
 * @author Administrator
 * SchedulerListener会在Scheduler的生命周期中关键事件发生时被调用。与Scheduler有关的事件包括:增加一个job/trigger,
 * 删除一个job/trigger,scheduler发生严重错误,关闭scheduler等。
 */
public class TimerSchedulerListener implements SchedulerListener {
	Logger logger = Logger.getLogger(TimerSchedulerListener.class);
	
	 @Override
	    public void jobScheduled(Trigger trigger) {
	        String jobName = trigger.getJobKey().getName();
	        logger.info(jobName +"部署");
	        System.out.println(jobName + "部署s");
	    }

	    @Override
	    public void jobUnscheduled(TriggerKey triggerKey) {
	        logger.info(triggerKey + "卸载");
	        System.out.println(triggerKey + "卸载");
	    }

	    @Override
	    public void triggerFinalized(Trigger trigger) {
	        logger.info("触发完成" + trigger.getJobKey().getName());
	        System.out.println("触发完成" + trigger.getJobKey().getName());
	    }

	    @Override
	    public void triggerPaused(TriggerKey triggerKey) {
	        logger.info(triggerKey + "暂停");
	        System.out.println(triggerKey + "暂停");
	    }

	    @Override
	    public void triggersPaused(String triggerGroup) {
	        logger.info("trigger group "+triggerGroup + "暂停");
	        System.out.println("trigger group "+triggerGroup + "暂停");
	    }

	    @Override
	    public void triggerResumed(TriggerKey triggerKey) {
	        logger.info(triggerKey + "从暂停中恢复");
	        System.out.println(triggerKey + "从暂停中恢复");
	    }

	    @Override
	    public void triggersResumed(String triggerGroup) {
	        logger.info("trigger group "+triggerGroup + "从暂停中恢复");
	        System.out.println("trigger group "+triggerGroup + "从暂停中恢复");
	    }

	    @Override
	    public void jobAdded(JobDetail jobDetail) {
	        logger.info(jobDetail.getKey()+"增加");
	        System.out.println(jobDetail.getKey()+"增加");
	    }

	    @Override
	    public void jobDeleted(JobKey jobKey) {
	        logger.info(jobKey+"删除");
	        System.out.println(jobKey+"删除");
	    }

	    @Override
	    public void jobPaused(JobKey jobKey) {
	        logger.info(jobKey+"暂停");
	        System.out.println(jobKey+"暂停");
	    }

	    @Override
	    public void jobsPaused(String jobGroup) {
	        logger.info("job group "+jobGroup+"暂停");
	        System.out.println("job group "+jobGroup+"暂停");
	    }

	    @Override
	    public void jobResumed(JobKey jobKey) {
	        logger.info(jobKey+"从暂停上恢复");
	        System.out.println(jobKey+"从暂停上恢复");
	    }

	    @Override
	    public void jobsResumed(String jobGroup) {
	        logger.info("job group "+jobGroup+"从暂停上恢复");
	        System.out.println("job group "+jobGroup+"从暂停上恢复");
	    }

	    @Override
	    public void schedulerError(String msg, SchedulerException cause) {
	        logger.error(msg, cause.getUnderlyingException());
	        logger.info("正常运行期间产生一个严重错误");
	        System.out.println("正常运行期间产生一个严重错误");
	    }

	    @Override
	    public void schedulerInStandbyMode() {
	        logger.info("Scheduler处于StandBy模式");
	        System.out.println("Scheduler处于StandBy模式");
	    }

	    @Override
	    public void schedulerStarted() {
	        logger.info("scheduler开启完成");
	        System.out.println("scheduler开启完成");
	    }

	    @Override
	    public void schedulerStarting() {
	        logger.info("scheduler正在开启");
	        System.out.println("scheduler正在开启");
	    }

	    @Override
	    public void schedulerShutdown() {
	        logger.info("scheduler停止");
	        System.out.println("scheduler停止");
	    }

	    @Override
	    public void schedulerShuttingdown() {
	        logger.info("scheduler正在停止");
	        System.out.println("scheduler正在停止");
	    }

	    @Override
	    public void schedulingDataCleared() {
	        logger.info("Scheduler中的数据被清除");
	        System.out.println("Scheduler中的数据被清除");
	    }
}

 任务调度与运行,及TimerSchedulerListener的创建与注册。

package com.ghuiqun.timer;

import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.EverythingMatcher;

import com.gzhuiqun.listener.TimerJobListener;
import com.gzhuiqun.listener.TimerSchedulerListener;
import com.gzhuiqun.listener.TimerTriggerListener;

public class TimerExample {
	// 创建 schedulerFactory 工厂
	private static SchedulerFactory scheduleFactory= new StdSchedulerFactory();
	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] data= {"s","t","r","i","n","g"};
		try {
			addJob("HelloJob2","HelloJobGroup","HelloTrigger2","HelloTriggerGroup",TimerJob.class,"0/1 * * * * ?",data);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**添加一个定时任务
	 * @param jobName 任务名
	 * @param jobGroupName 任务组名
	 * @param triggerName 触发器名
	 * @param triggerGroupName 触发器组名
	 * @param jobClass 任务类名
	 * @param cron 时间
	 * @throws InterruptedException 
	 */
	public static void addJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName
			,Class<? extends Job> jobClass,String cron,String[] data) throws InterruptedException {
		try {
			//通过scheduleFactory创建任务调度器
			Scheduler scheduler = scheduleFactory.getScheduler();
			
			//创建 jobDetail 实例,绑定 Job 实现类
			// 指明 job 的名称,所在组的名称,以及绑定 job 类
			JobDetail job = (JobDetail) JobBuilder.newJob(jobClass)
					.withIdentity(jobName,jobGroupName)
					//.requestRecovery() // 执行中应用发生故障,需要重新执行
					.build();
					// 初始化参数传递到 job
					job.getJobDataMap().put("data",data);
					
			// 定义调度触发规则CronTrigger
			//指明 CronTrigger 的名称,所在组的名称,触发时间
			Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
					.withIdentity(triggerName,triggerGroupName)
					.startNow()
					.withSchedule(CronScheduleBuilder.cronSchedule(cron))
					.build();
			
			// 把作业和触发器注册到任务调度中
			scheduler.scheduleJob(job,trigger);
			
	        
	        // 创建SchedulerListener
	        scheduler.getListenerManager().addSchedulerListener(new TimerSchedulerListener());
	        
	        // 移除对应的SchedulerListener
//	        scheduler.getListenerManager().removeSchedulerListener(new TimerSchedulerListener());
			//启动
			if(!scheduler.isShutdown()) {
				scheduler.start();
				System.out.println("开始调度任务");
			}
			
			Thread.sleep(5000);
	        
	        scheduler.shutdown();
	        
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

结果:

2019-04-03 11:17:41  [ main:546 ] - [ INFO ]  scheduler正在开启
2019-04-03 11:17:41  [ main:606 ] - [ INFO ]  scheduler开启完成
2019-04-03 11:17:41  [ MyScheduler_Worker-1:641 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:41 CST 2019
2019-04-03 11:17:41  [ MyScheduler_Worker-2:657 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:41 CST 2019
2019-04-03 11:17:41  [ MyScheduler_Worker-3:668 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:41 CST 2019
2019-04-03 11:17:41  [ MyScheduler_Worker-4:680 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:41 CST 2019
2019-04-03 11:17:41  [ MyScheduler_Worker-5:692 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:41 CST 2019
2019-04-03 11:17:42  [ MyScheduler_Worker-6:1423 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:42 CST 2019
2019-04-03 11:17:42  [ MyScheduler_Worker-7:1454 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:42 CST 2019
2019-04-03 11:17:42  [ MyScheduler_Worker-8:1478 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:42 CST 2019
2019-04-03 11:17:43  [ MyScheduler_Worker-9:2429 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:43 CST 2019
2019-04-03 11:17:43  [ MyScheduler_Worker-10:2462 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:43 CST 2019
2019-04-03 11:17:43  [ MyScheduler_Worker-1:2477 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:43 CST 2019
2019-04-03 11:17:44  [ MyScheduler_Worker-2:3414 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:44 CST 2019
2019-04-03 11:17:44  [ MyScheduler_Worker-3:3424 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:44 CST 2019
2019-04-03 11:17:44  [ MyScheduler_Worker-4:3435 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:44 CST 2019
2019-04-03 11:17:45  [ MyScheduler_Worker-5:4420 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:45 CST 2019
2019-04-03 11:17:45  [ MyScheduler_Worker-6:4446 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:45 CST 2019
2019-04-03 11:17:45  [ MyScheduler_Worker-7:4466 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:45 CST 2019
2019-04-03 11:17:46  [ MyScheduler_Worker-8:5424 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:46 CST 2019
2019-04-03 11:17:46  [ MyScheduler_Worker-9:5450 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:46 CST 2019
2019-04-03 11:17:46  [ MyScheduler_Worker-10:5475 ] - [ INFO ]  坚持 坚持  在坚持,永不放弃Wed Apr 03 11:17:46 CST 2019
2019-04-03 11:17:46  [ main:5607 ] - [ INFO ]  Scheduler处于StandBy模式
2019-04-03 11:17:46  [ main:5607 ] - [ INFO ]  scheduler正在停止
2019-04-03 11:17:46  [ main:5613 ] - [ INFO ]  scheduler停止

猜你喜欢

转载自blog.csdn.net/little__SuperMan/article/details/88987578
今日推荐