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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Quartz-JobListener解读

發(fā)布時(shí)間:2025/3/21 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Quartz-JobListener解读 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 概述
  • 步驟簡(jiǎn)述
  • 全局/非全局監(jiān)聽(tīng)器
  • JobListener 任務(wù)監(jiān)聽(tīng)器 示例
    • JobListener源碼
    • 完整示例
  • 示例源碼

概述

在某個(gè)所關(guān)注事件發(fā)生時(shí),監(jiān)聽(tīng)器提供了一種方便且非侵入性的機(jī)制來(lái)獲得這一通知。Quartz 提供了三種類型的監(jiān)聽(tīng)器:監(jiān)聽(tīng) Job 的,監(jiān)聽(tīng) Trigger 的,和監(jiān)聽(tīng) Scheduler 自已的。

本博文闡述如何應(yīng)用每一種類型來(lái)更好的管理你的 Quartz 應(yīng)用,并獲悉到什么事件正在發(fā)生。

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


步驟簡(jiǎn)述

要?jiǎng)?chuàng)建一個(gè)Listener, 只需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)了org.quartz.TriggerListener或org.quartz.JobListener接口的對(duì)象即可。

在運(yùn)行的時(shí)候,將Listeners注冊(cè)進(jìn)scheduler, 而且必須給一個(gè)name(可以通過(guò)他們的getName()方法獲取Listener的name)。

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

Listener通過(guò)scheduler的ListenerManager來(lái)注冊(cè),其中的Matcher 里描述哪個(gè)Jobs、Triggers需要被監(jiān)聽(tīng)。

注意:
LListeners在運(yùn)行的時(shí)候被注冊(cè)進(jìn)scheduler, 而不是保存在JobStore。Listener是和你的應(yīng)用集成在一起的,這樣每次你的應(yīng)用運(yùn)行的時(shí)候,都會(huì)在scheduler中重新注冊(cè)listeners。


全局/非全局監(jiān)聽(tīng)器

JobListener 和 TriggerListener 可被注冊(cè)為全局或非全局監(jiān)聽(tīng)器。

  • 全局監(jiān)聽(tīng)器能接收到所有的 Job/Trigger 的事件通知。

  • 非全局監(jiān)聽(tīng)器(或者說(shuō)是一個(gè)標(biāo)準(zhǔn)的監(jiān)聽(tīng)器) 只能接收到那些在其上已注冊(cè)了監(jiān)聽(tīng)器的 Job 或 Triiger 的事件。

你要注冊(cè)你的監(jiān)聽(tīng)器為全局或非全局的需依據(jù)你特定的應(yīng)用需要。

全局監(jiān)聽(tīng)器是主動(dòng)意識(shí)的,它們?yōu)榱藞?zhí)行它們的任務(wù)而熱切的去尋找每一個(gè)可能的事件。通常全局監(jiān)聽(tīng)器要做的工作不用指定到特定的 Job 或 Trigger。非全局監(jiān)聽(tīng)器一般是被動(dòng)意識(shí)的,它們?cè)谒P(guān)注的 Trigger 激發(fā)之前或是 Job 執(zhí)行之前什么事也不做。因此,非全局的監(jiān)聽(tīng)器比起全局監(jiān)聽(tīng)器而言更適合于修改或增加 Job 執(zhí)行的工作。這有點(diǎn)像知名的裝飾設(shè)計(jì)模式的裝飾器。

全局 監(jiān)聽(tīng)器

scheduler.addGlobalTriggerListener(new SimpleMyTriggerListener())

非全局監(jiān)聽(tīng)器

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

JobListener 任務(wù)監(jiān)聽(tīng)器 示例

JobListener源碼

我們先來(lái)看下JobListener的源碼:

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

  • jobToBeExecuted() :Scheduler 在 JobDetail 將要被執(zhí)行時(shí)調(diào)用這個(gè)方法。

  • jobExecutionVetoed() :Scheduler 在 JobDetail 即將被執(zhí)行,但又被 TriggerListener否決了時(shí)調(diào)用這個(gè)方法。

  • jobWasExecuted() :Scheduler 在 JobDetail 被執(zhí)行之后調(diào)用這個(gè)方法。


自定義監(jiān)聽(tīng)器

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

注冊(cè)監(jiān)聽(tīng)器

MyJobListener myJobListener=new MyJobListener(); // 添加一個(gè)特定的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"));// 添加多個(gè)特定組的所有jobs scheduler.getListenerManager().addJobListener(myJobListener, or(jobGroupEquals("myJobGroup"), jobGroupEquals("yourGroup")));// 添加所有jobs scheduler.getListenerManager().addJobListener(myJobListener, allJobs());

有了Listeners以后,當(dāng)應(yīng)用需要在某些事件發(fā)生以后去通知你的應(yīng)用,這時(shí)就不需要Job去明確地去告知你的應(yīng)用了。


完整示例

添加一個(gè)jobListener,監(jiān)聽(tīng)到j(luò)ob1執(zhí)行后,再觸發(fā)一個(gè)job2任務(wù)

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 - 任務(wù)key "+ jobKey+ "執(zhí)行時(shí)間:"+ 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 - 任務(wù)key "+ jobKey+ "執(zhí)行時(shí)間:"+ 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監(jiān)聽(tīng)器* * getName() :返回一個(gè)字符串用以說(shuō)明 JobListener 的名稱。對(duì)于注冊(cè)為全局的監(jiān)聽(tīng)器,getName()* 主要用于記錄日志,對(duì)于由特定 Job 引用的 JobListener,注冊(cè)在 JobDetail* 上的監(jiān)聽(tīng)器名稱必須匹配從監(jiān)聽(tīng)器上 getName() 方法的返回值.* * jobToBeExecuted() :Scheduler 在 JobDetail 將要被執(zhí)行時(shí)調(diào)用這個(gè)方法。* * jobExecutionVetoed() :Scheduler 在 JobDetail 即將被執(zhí)行,但又被* TriggerListener 否決了時(shí)調(diào)用這個(gè)方法。* * jobWasExecuted() :Scheduler 在 JobDetail 被執(zhí)行之后調(diào)用這個(gè)方法。* * @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監(jiān)聽(tīng)器:MyJobListener.jobToBeExecuted()");}@Overridepublic void jobExecutionVetoed(JobExecutionContext context) {System.out.println("Job監(jiān)聽(tīng)器:MyJobListener.jobExecutionVetoed()");}@Overridepublic void jobWasExecuted(JobExecutionContext context,JobExecutionException jobException) {System.out.println("Job監(jiān)聽(tīng)器:MyJobListener.jobWasExecuted()");// 設(shè)置另外一個(gè)job執(zhí)行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("無(wú)法安排job2!");e.printStackTrace();}}}

調(diào)度類

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();// 設(shè)置監(jiān)聽(tīng)器JobListener jobListener = new MyJobListener();Matcher<JobKey> matcher = KeyMatcher.keyEquals(job.getKey());scheduler.getListenerManager().addJobListener(jobListener, matcher);// 將job任務(wù)加入到調(diào)度器scheduler.scheduleJob(job, trigger);// 開(kāi)始任務(wù)System.out.println("------- 開(kāi)始執(zhí)行調(diào)度器 Scheduler ----------------");scheduler.start();try {System.out.println("------- 等待 30 秒... --------------");Thread.sleep(30L * 1000L);} catch (Exception e) {e.printStackTrace();}scheduler.shutdown(true);System.out.println("------- 關(guān)閉調(diào)度器 -----------------");SchedulerMetaData metaData = scheduler.getMetaData();System.out.println("~~~~~~~~~~ 執(zhí)行了 "+ metaData.getNumberOfJobsExecuted() + " 個(gè) jobs.");}}

運(yùn)行結(jié)果

------- 初始化 ---------------------- 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 ------- 開(kāi)始執(zhí)行調(diào)度器 Scheduler ---------------- INFO QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. ------- 等待 30... -------------- Job監(jiān)聽(tīng)器:MyJobListener.jobToBeExecuted()Job1 - 任務(wù)key group1.job1執(zhí)行時(shí)間:2017-11-16 17:58:54 Job監(jiān)聽(tīng)器:MyJobListener.jobWasExecuted()Job2 - 任務(wù)key DEFAULT.job2執(zhí)行時(shí)間: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. ------- 關(guān)閉調(diào)度器 ----------------- ~~~~~~~~~~ 執(zhí)行了 2 個(gè) jobs.

示例源碼

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

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

總結(jié)

以上是生活随笔為你收集整理的Quartz-JobListener解读的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。