日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Quartz-JobListener解读

發布時間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Quartz-JobListener解读 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 概述
  • 步驟簡述
  • 全局/非全局監聽器
  • JobListener 任務監聽器 示例
    • JobListener源碼
    • 完整示例
  • 示例源碼

概述

在某個所關注事件發生時,監聽器提供了一種方便且非侵入性的機制來獲得這一通知。Quartz 提供了三種類型的監聽器:監聽 Job 的,監聽 Trigger 的,和監聽 Scheduler 自已的。

本博文闡述如何應用每一種類型來更好的管理你的 Quartz 應用,并獲悉到什么事件正在發生。

參考官方Demo:
http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-07.html


步驟簡述

要創建一個Listener, 只需要創建一個實現了org.quartz.TriggerListener或org.quartz.JobListener接口的對象即可。

在運行的時候,將Listeners注冊進scheduler, 而且必須給一個name(可以通過他們的getName()方法獲取Listener的name)。

除了繼承接口,類也可以繼承JobListenerSupport或TriggerListenerSupport,重寫你感興趣的event。

Listener通過scheduler的ListenerManager來注冊,其中的Matcher 里描述哪個Jobs、Triggers需要被監聽。

注意:
LListeners在運行的時候被注冊進scheduler, 而不是保存在JobStore。Listener是和你的應用集成在一起的,這樣每次你的應用運行的時候,都會在scheduler中重新注冊listeners。


全局/非全局監聽器

JobListener 和 TriggerListener 可被注冊為全局或非全局監聽器。

  • 全局監聽器能接收到所有的 Job/Trigger 的事件通知。

  • 非全局監聽器(或者說是一個標準的監聽器) 只能接收到那些在其上已注冊了監聽器的 Job 或 Triiger 的事件。

你要注冊你的監聽器為全局或非全局的需依據你特定的應用需要。

全局監聽器是主動意識的,它們為了執行它們的任務而熱切的去尋找每一個可能的事件。通常全局監聽器要做的工作不用指定到特定的 Job 或 Trigger。非全局監聽器一般是被動意識的,它們在所關注的 Trigger 激發之前或是 Job 執行之前什么事也不做。因此,非全局的監聽器比起全局監聽器而言更適合于修改或增加 Job 執行的工作。這有點像知名的裝飾設計模式的裝飾器。

全局 監聽器

scheduler.addGlobalTriggerListener(new SimpleMyTriggerListener())

非全局監聽器

scheduler.addTriggerListener( triggerListener ); trigger.addTriggerListener( triggerListener.getName() );

JobListener 任務監聽器 示例

JobListener源碼

我們先來看下JobListener的源碼:

  • getName() :返回一個字符串用以說明 JobListener 的名稱。對于注冊為全局的監聽器,getName()主要用于記錄日志,對于由特定 Job 引用的JobListener,注冊在 JobDetail 上的監聽器名稱必須匹配從監聽器getName() 方法的返回值。

  • jobToBeExecuted() :Scheduler 在 JobDetail 將要被執行時調用這個方法。

  • jobExecutionVetoed() :Scheduler 在 JobDetail 即將被執行,但又被 TriggerListener否決了時調用這個方法。

  • jobWasExecuted() :Scheduler 在 JobDetail 被執行之后調用這個方法。


自定義監聽器

import org.quartz.*;public class MyJobListener implements JobListener {@Overridepublic String getName() {return "MyJobListener";}@Overridepublic void jobExecutionVetoed(JobExecutionContext arg0) {System.out.println("Job監聽器:MyJobListener.jobExecutionVetoed()");}@Overridepublic void jobToBeExecuted(JobExecutionContext arg0) {System.out.println("Job監聽器:MyJobListener.jobToBeExecuted()");}@Overridepublic void jobWasExecuted(JobExecutionContext arg0,JobExecutionException arg1) {System.out.println("Job監聽器:MyJobListener.jobWasExecuted()");}}

注冊監聽器

MyJobListener myJobListener=new MyJobListener(); // 添加一個特定的job scheduler.getListenerManager().addJobListener(myJobListener, KeyMatcher.jobKeyEquals(new JobKey("myJobName", "myJobGroup")));

上面的代碼就可以變成:

scheduler.getListenerManager().addJobListener(myJobListener, jobKeyEquals(jobKey("myJobName", "myJobGroup")));// 添加特定組的所有jobs scheduler.getListenerManager().addJobListener(myJobListener, jobGroupEquals("myJobGroup"));// 添加多個特定組的所有jobs scheduler.getListenerManager().addJobListener(myJobListener, or(jobGroupEquals("myJobGroup"), jobGroupEquals("yourGroup")));// 添加所有jobs scheduler.getListenerManager().addJobListener(myJobListener, allJobs());

有了Listeners以后,當應用需要在某些事件發生以后去通知你的應用,這時就不需要Job去明確地去告知你的應用了。


完整示例

添加一個jobListener,監聽到job1執行后,再觸發一個job2任務

Job1.java

package com.xgj.quartz.quartzItself.listener.jobListener;import java.text.SimpleDateFormat; import java.util.Date;import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey;public class Job1 implements Job {public void execute(JobExecutionContext context)throws JobExecutionException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");JobKey jobKey = context.getJobDetail().getKey();System.out.println("\nJob1 - 任務key "+ jobKey+ "執行時間:"+ sdf.format(new Date()));} }

Job2.java

package com.xgj.quartz.quartzItself.listener.jobListener;import java.text.SimpleDateFormat; import java.util.Date;import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey;public class Job2 implements Job {public void execute(JobExecutionContext context)throws JobExecutionException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");JobKey jobKey = context.getJobDetail().getKey();System.err.println("\nJob2 - 任務key "+ jobKey+ "執行時間:"+ sdf.format(new Date()));} }

自定義JobListener

package com.xgj.quartz.quartzItself.listener.jobListener;import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobListener; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerBuilder;/*** * * @ClassName: MyJobListener* * @Description: 自定義Job監聽器* * getName() :返回一個字符串用以說明 JobListener 的名稱。對于注冊為全局的監聽器,getName()* 主要用于記錄日志,對于由特定 Job 引用的 JobListener,注冊在 JobDetail* 上的監聽器名稱必須匹配從監聽器上 getName() 方法的返回值.* * jobToBeExecuted() :Scheduler 在 JobDetail 將要被執行時調用這個方法。* * jobExecutionVetoed() :Scheduler 在 JobDetail 即將被執行,但又被* TriggerListener 否決了時調用這個方法。* * jobWasExecuted() :Scheduler 在 JobDetail 被執行之后調用這個方法。* * @author: Mr.Yang* * @date: 2017年11月16日 下午3:57:35*/ public class MyJobListener implements JobListener {@Overridepublic String getName() {return "MyJobListerner";}@Overridepublic void jobToBeExecuted(JobExecutionContext context) {System.out.println("Job監聽器:MyJobListener.jobToBeExecuted()");}@Overridepublic void jobExecutionVetoed(JobExecutionContext context) {System.out.println("Job監聽器:MyJobListener.jobExecutionVetoed()");}@Overridepublic void jobWasExecuted(JobExecutionContext context,JobExecutionException jobException) {System.out.println("Job監聽器:MyJobListener.jobWasExecuted()");// 設置另外一個job執行JobDetail job2 = JobBuilder.newJob(Job2.class).withIdentity("job2").build();Trigger trigger = TriggerBuilder.newTrigger().withIdentity("job2Trigger").startNow().build();try {context.getScheduler().scheduleJob(job2, trigger);} catch (SchedulerException e) {System.err.println("無法安排job2!");e.printStackTrace();}}}

調度類

package com.xgj.quartz.quartzItself.listener.jobListener;import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger;import org.quartz.JobDetail; import org.quartz.JobKey; import org.quartz.JobListener; import org.quartz.Matcher; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.SchedulerMetaData; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.matchers.KeyMatcher;public class JobListenerDemo {public static void main(String[] args) throws Exception {System.out.println("------- 初始化 ----------------------");// SchedulerSchedulerFactory schedulerFactory = new StdSchedulerFactory();Scheduler scheduler = schedulerFactory.getScheduler();// JobJobDetail job = newJob(Job1.class).withIdentity("job1", "group1").build();// Tirgger Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startNow().build();// 設置監聽器JobListener jobListener = new MyJobListener();Matcher<JobKey> matcher = KeyMatcher.keyEquals(job.getKey());scheduler.getListenerManager().addJobListener(jobListener, matcher);// 將job任務加入到調度器scheduler.scheduleJob(job, trigger);// 開始任務System.out.println("------- 開始執行調度器 Scheduler ----------------");scheduler.start();try {System.out.println("------- 等待 30 秒... --------------");Thread.sleep(30L * 1000L);} catch (Exception e) {e.printStackTrace();}scheduler.shutdown(true);System.out.println("------- 關閉調度器 -----------------");SchedulerMetaData metaData = scheduler.getMetaData();System.out.println("~~~~~~~~~~ 執行了 "+ metaData.getNumberOfJobsExecuted() + " 個 jobs.");}}

運行結果

------- 初始化 ---------------------- INFO StdSchedulerFactory - Using default implementation for ThreadExecutor INFO SimpleThreadPool - Job execution threads will use class loader of thread: main INFO SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl INFO QuartzScheduler - Quartz Scheduler v.2.2.3 created. INFO RAMJobStore - RAMJobStore initialized. INFO QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.2.3) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.NOT STARTED.Currently in standby mode.Number of jobs executed: 0Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.INFO StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' INFO StdSchedulerFactory - Quartz scheduler version: 2.2.3 ------- 開始執行調度器 Scheduler ---------------- INFO QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. ------- 等待 30... -------------- Job監聽器:MyJobListener.jobToBeExecuted()Job1 - 任務key group1.job1執行時間:2017-11-16 17:58:54 Job監聽器:MyJobListener.jobWasExecuted()Job2 - 任務key DEFAULT.job2執行時間:2017-11-16 17:58:54 INFO QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down. INFO QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused. INFO QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete. ------- 關閉調度器 ----------------- ~~~~~~~~~~ 執行了 2 個 jobs.

示例源碼

代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Quartz-JobListener解读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。