您的位置 首页 > 德语词汇

quartz是什么意思(一文带你入坑)

大家好,感谢邀请,今天来为大家分享一下quartz是什么意思的问题,以及和一文带你入坑的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

大家好,我是小菜,一个渴望在互联网行业做到蔡不菜的小菜。可柔可刚,点赞则柔,白嫖则刚!死鬼~看完记得给我来个三连哦!

本文主要介绍Quartz的使用如有需要,可以参考如有帮助,不忘点赞?微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

quartz是什么意思(一文带你入坑)

quartz是一款开源且丰富特性的**“任务调度库”,能够集成与任何的java**应用,下到独立应用,大到电子商业系统。quartz就是基于java实现的任务调度框架,用于执行你想要执行的任何任务。

什么是任务调度?任务调度就是我们系统中创建了N个任务,每个任务都有指定的时间进行执行,而这种多任务的执行策略就是任务调度。

quartz的作用就是让任务调度变得更加丰富,高效,安全,而且是基于Java实现的,这样子开发者只需要调用几个接口坐下简单的配置,即可实现上述需求。

我们想要调度的任务都必须实现org.quartz.job接口,然后实现接口中定义的execute()方法即可

Trigger作为执行任务的调度器。我们如果想要凌晨1点执行备份数据的任务,那么Trigger就会设置凌晨1点执行该任务。其中Trigger又分为SimpleTriggerCronTrigger两种

Scheduler为任务的调度器,它会将任务Job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job

上面我们大概介绍了Quartz,那么该如何使用了,请往下看:

<!--quartz-->\n<dependency>\n<groupId>org.quartz-scheduler</groupId>\n<artifactId>quartz</artifactId>\n<version>2.3.2</version>\n</dependency>\n自定义任务

publicclassTestJobimplementsJob{\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nStringdata=LocalDateTime.now()\n.format(DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));\nSystem.out.println("STARTDATABACKUP,currenttime:"+data);\n}\n}\n创建任务调度

publicclassTestScheduler{\npublicstaticvoidmain(String[]args)throwsException{\n//获取任务调度的实例\nSchedulerscheduler=StdSchedulerFactory.getDefaultScheduler();\n//定义任务调度实例,并与TestJob绑定\nJobDetailjob=JobBuilder.newJob(TestJob.class)\n.withIdentity("testJob","testJobGroup")\n.build();\n//定义触发器,会马上执行一次,接着5秒执行一次\nTriggertrigger=TriggerBuilder.newTrigger()\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\n//使用触发器调度任务的执行\nscheduler.scheduleJob(job,trigger);\n//开启任务\nscheduler.start();\n}\n}\n/**OUTPUT:\nSTARTDATABACKUP,currenttime:2020-11-1721:48:30\nSTARTDATABACKUP,currenttime:2020-11-1721:48:35\nSTARTDATABACKUP,currenttime:2020-11-1721:48:40\nSTARTDATABACKUP,currenttime:2020-11-1721:48:45\n**/\n

通过以上示例,我们成功执行了一个任务,我们来回顾一下程序中出现的几个重要参数:

Job是工作任务调度的接口,任务类需要实现该接口。该接口中定义了execute方法,我们需要在里面编写任务执行的业务逻辑,类似JDK提供的TimeTask类的run方法。每次调度器执行Job时,在调用execute方法之前都会创建一个新的Job实例,当调用完成后,关联的Job对象示例会被释放,释放的实例会被垃圾回收机制回收

JobDetail是为Job实例提供了许多设置属性,以及JobDetailMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。

JobDataMapjobDataMap=jobDetail.getJobDataMap();\nStringname=jobDetail.getKey().getName();\nStringgroup=jobDetail.getKey().getGroup();\nStringjobName=jobDetail.getJobClass().getName();\n

两者之间的关系:

JobDetail定义的是任务数据,而真正的执行逻辑是是在Job中。这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而采用JobDetail&Job方式,Scheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访文的问题

Scheduler调用一个Job,就会将JobExecutionContext传递给Jobexecute()方法。这样子在Job中就能通过JobExecutionContext对象来访问到Quartz运行时候的环境以及Job本身的明细数据。

顾名思义JobDataMap是一个Map,它实现了JDK中的Map接口,可以用来存取基本数据类型,也可以用来转载任何可序列化的数据对象,当Job实例对象被执行时这些参数对象会传递给它。示例如下:

JobDetailjobDetail=JobBuilder.newJob(TestJob.class)\n.usingJobData("testJobDetail","jobDetail数据存放")\n.withIdentity("testJob","testJobGroup")\n.build();\nTriggertrigger=TriggerBuilder.newTrigger()\n.usingJobData("testTrigger","trigger数据存放")\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\nJob任务类:

publicclassTestJobimplementsJob{\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nSystem.out.println(jobExecutionContext.getJobDetail()\n.getJobDataMap().get("testJobDetail"));\nSystem.out.println(jobExecutionContext.getTrigger()\n.getJobDataMap().get("testTrigger"));\n}\n}\n/**OUTPUT:\njobDetail数据存放\ntrigger数据存放\n**/\n

以上我们是通过getJobDataMap()方法来获取JobDataMap中的值,我们还可以使用另外一种方式来获取:

publicclassTestJobimplementsJob{\n\nprivateStringtestJobDetail;\n\npublicvoidsetTestJobDetail(StringtestJobDetail){\nthis.testJobDetail=testJobDetail;\n}\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nSystem.out.println(testJobDetail);\n}\n}\n/**OUTPUT:\njobDetail数据存放\n**/\n

**以上方式便是:**只要我们在Job实现类中添加对应key的setter方法,那么Quartz框架默认的JobFactory实现类在初始化Job实例对象时回自动地调用这些setter方法

注:如果遇到同名的key,比如我们在JobDetail中存放值的key与在Trigger中存放值的key相同,那么最终Trigger的值会覆盖掉JobDetail中的值,示例如下:

JobDetailjobDetail=JobBuilder.newJob(TestJob.class)\n.usingJobData("testInfo","jobDetail数据存放")\n.withIdentity("testJob","testJobGroup")\n.build();\nTriggertrigger=TriggerBuilder.newTrigger()\n.usingJobData("testInfo","trigger数据存放")\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\nJob任务类:会输出Trigger中存放的值

publicclassTestJobimplementsJob{\n\nprivateStringtestInfo;\n\npublicvoidsetTestInfo(StringtestInfo){\nthis.testInfo=testInfo;\n}\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nSystem.out.println(testInfo);\n}\n}\n/**OUTPUT:\ntrigger数据存放\n**/\n4.Job的状态

如果我们有个需求是统计每个任务的执行次数,那么你会怎么做?

也许你会想到使用上面说到的JobDataMap,那就让我们尝试下:

//我们在JobDataMap中定义了一个值为0的初始值\nJobDetailjobDetail=JobBuilder.newJob(TestJob.class)\n.usingJobData("executeCount",0)\n.withIdentity("testJob","testJobGroup")\n.build();\nJob任务类

@Slf4j\npublicclassTestJobimplementsJob{\n\nprivateIntegerexecuteCount;\n\npublicvoidsetExecuteCount(IntegerexecuteCount){\nthis.executeCount=executeCount;\n}\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nStringdata=LocalDateTime.now()\n.format(DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));\nlog.info("executecount:{},currenttime:{}",\n++executeCount,data);\n//将累加的count存入JobDataMap中\njobExecutionContext.getJobDetail()\n.getJobDataMap().put("executeCount",executeCount);\n}\n}\n/**OUTPUT:\nexecutecount:1,currenttime:2020-11-1722:38:48\nexecutecount:1,currenttime:2020-11-1722:38:52\nexecutecount:1,currenttime:2020-11-1722:38:57\n**/\n

按照上面的想法我们写出了这部分代码,但貌似打脸了,结果并没有按照我们预计的发展,是逻辑不对吗,貌似写的也没什么问题。这时你会不会回忆到上面我讲过的一句话:"在调用execute方法之前都会创建一个新的Job实例",这就牵引出了Job状态的概念:

每次调用时都会创建一个新的JobDataMap

多次Job调用可以持有一些状态信息,这些状态信息存储在JobDataMap

那么问题来了,如果让Job变成有状态?这个时候我们可以借助一个注解:@PersistJobDataAfterExecution,加上这个注解后,我们再来试下:

@Slf4j\n@PersistJobDataAfterExecution\npublicclassTestJobimplementsJob{\n\nprivateIntegerexecuteCount;\n\npublicvoidsetExecuteCount(IntegerexecuteCount){\nthis.executeCount=executeCount;\n}\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext)throwsJobExecutionException{\nStringdata=LocalDateTime.now().\nformat(DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));\nlog.info("executecount:{},currenttime:{}",\n++executeCount,data);\n//将累加的count存入JobDataMap中\njobExecutionContext.getJobDetail().\ngetJobDataMap().put("executeCount",executeCount);\n}\n}\n/**OUTPUT:\nexecutecount:1,currenttime:2020-11-1722:28:48\nexecutecount:2,currenttime:2020-11-1722:28:52\nexecutecount:3,currenttime:2020-11-1722:28:57\n**/\n

可以看到加了@PersistJobDataAfterExecution,我们已经成功达到了我们的目的。

经过以上示例,我们已经大概知道了Quartz的组成,我们定义了任务之后,需要用触发器Trigger去指定Job的执行时间,执行间隔,运行次数等,那么JobTrigger的结合,我们中间还需要Scheduler去调度,三者关系大致如下:

其中Trigger又有几种实现类如下:

大致有四个实现类,但是我们平时用的最多的还是CronTriggerImplSimpleTriggerImpl

我们如果想要定义任务何时执行,何时结束,我们可以这样做:

DatestartTime=newDate();\nstartTime.setTime(startTime.getTime()+5000);\nDateendTime=newDate();\nendTime.setTime(startTime.getTime()+10000);\nTriggertrigger=TriggerBuilder.newTrigger()\n.usingJobData("testInfo","trigger数据存放")\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.startAt(startTime)\n.endAt(endTime)\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\nJob任务类

@Slf4j\n@PersistJobDataAfterExecution\npublicclassTestJobimplementsJob{\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext)throwsJobExecutionException{\nTriggertrigger=jobExecutionContext.getTrigger();\nlog.info("starttime:{},endtime:{}",\ntrigger.getStartTime(),trigger.getEndTime());\n}\n}\n/**OUTPUT:\nstarttime:ThuNov1722:42:51CST2020,endtime:ThuNov1722:43:01CST2020\nstarttime:ThuNov1722:42:51CST2020,endtime:ThuNov1722:43:01CST2020\n**/\n

通过控制台可以看到,任务执行了两次便已经停止了,因为已经超过了停止时间ThuNov1722:43:01CST2020

我们上面看到示例,用到的都是SimpleTriggerSimpleTrigger对于设置和使用是最为简单的一种QuartzTrigger,它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行n次的Job任务所设计的。

比如我想要在一个指定的时间段内执行一次任务,我们只需要这样写:

Triggertrigger=TriggerBuilder.newTrigger()\n.withIdentity("testTrigger","testTriggerGroup")\n.startAt(startTime)//自定义执行时间\n.build();\n

再者我想在指定的时间间隔内多次执行该任务,我们可以这样写:

Triggertrigger=TriggerBuilder.newTrigger()\n.withIdentity("testTrigger","testTriggerGroup")\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.withRepeatCount(2))//每5秒执行一次,连续执行3次后停止,从0开始计数\n.build();\n

我们来总结一下上面的示例:

SimpleTrigger执行间隔时间触发的相比,CronTrigger更加灵活,它是基于日历的作业调度器。使用CronTrigger我们可以执行某个时间点执行,例如“每天的凌晨1点执行”、“每个工作日的12点执行”,也可以像SimpleTrigger那样执行一个开始时间和结束时间运行任务

学习CronTrigger之前我们得先学习Cron表达式

Cron表达式是用来配置CronTrigger实例,它是一个由7个子表达式组成的字符串,每个字符都表示不同的日程细节:

可用在所有字段中,表示对应时间域的每一个时刻,例如,*****在分钟字段时,表示“每分钟”

该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符

表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12

表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五

x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y

该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五

该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围

该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发

Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。

"0010,14,16**?"每天上午10点,下午2点,4点\n"00/309-17**?"朝九晚五工作时间内每半小时,从0分开始每隔30分钟发送一次\n"0012?*WED"表示每个星期三中午12点\n"0012**?"每天中午12点触发\n"01510?**"每天上午10:15触发\n"01510**?"每天上午10:15触发\n"01510**?*"每天上午10:15触发\n"01510**?2005"2005年的每天上午10:15触发\n"0*14**?"在每天下午2点到下午2:59期间的每1分钟触发\n"00/5514**?"在每天下午2点到下午2:55期间,从0开始到55分钟触发\n"00-514**?"在每天下午2点到下午2:05期间的每1分钟触发\n"010,4414?3WED"每年三月的星期三的下午2:10和2:44触发\n"01510?*MON-FRI"周一至周五的上午10:15触发\n"0151015*?"每月15日上午10:15触发\n"01510L*?"每月最后一日的上午10:15触发\n"01510?*6L"每月的最后一个星期五上午10:15触发\n"01510?*6L2002-2005"2002年至2005年的每月的最后一个星期五上午10:15触发\n"01510?*6#3"每月的第三个星期五上午10:15触发\n使用示例

Triggertrigger=TriggerBuilder.newTrigger()\n.withIdentity("testTrigger","testTriggerGroup")\n.withSchedule(CronScheduleBuilder.cronSchedule("0/5**64?"))\n.build();\n6.Scheduler

Quartz是以模块的方式构建的,JobTrigger之间的结合需要靠Scheduler

Schedulerscheduler=StdSchedulerFactory.getDefaultScheduler();\n

创建是通过Quartz默认的SchedulerFactory,我们可以使用自定义参数(Properties)来创建和初始化Quartz调度器,配置参数一般存储在quartz.properties中。

我们上面是通过scheduleJob()方法来结合JobTrigger,这个方法有个时间类型的返回值,我们可以获取到调度器开始的时间:

Datedate=scheduler.scheduleJob(jobDetail,trigger);\n

关联完任务和触发器,我们就可以启动任务调度了:

scheduler.start();\n

将任务调度挂起(暂停):

scheduler.standby();\n

将任务关闭:

shutdown(true);//表示等待所有正在执行的job执行完毕之后,再关闭Scheduler\nshutdown(false);//表示直接关闭Scheduler\n

我们再来了解下quartz.properties文件,先看一个示例:

也可以编写程序代码操作quartz.properties文件的内容:

publicclassQuartzProperties{\n\npublicstaticvoidmain(String[]args){\n//创建工厂实例\nStdSchedulerFactoryfactory=newStdSchedulerFactory();\n\n//创建配置工厂的属性对象\nPropertiesprops=newProperties();\nprops.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,"org.quartz.simpl.SimpleThreadPool");//线程池定义\nprops.put("org.quartz.threadPool.threadCount","5");//默认Scheduler的线程数\n\ntry{\n//使用定义的属性初始化工厂\nfactory.initialize(props);\nSchedulerscheduler=factory.getScheduler();\nscheduler.start();\n}catch(SchedulerExceptione){\ne.printStackTrace();\n}\n}\n}\n

通过Properties设置工厂属性的缺点在用硬编码,假如需要修改例子中线程数量,将不得不修改代码,然后重新编译,所以不推荐使用。

Quartz实战中我们了解到三个核心模块分别是JobTriggerScheduler,既然Quartz中存在监听器,相应的,这三者也分别有对应的监听器。监听器的作用便是用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知

任务调度中,与任务Job相关的事件包括:Job开始要执行的提示,执行完成的提示,接口如下:

@Slf4j\n@PersistJobDataAfterExecution\npublicclassTestJobimplementsJob{\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nSystem.out.println("TestJob执行啦");\n}\n}\nJobListener

publicclassMyJobListenerimplementsJobListener{\n@Override\npublicStringgetName(){\nStringname=getClass().getSimpleName();\nSystem.out.println("监听器的名称是:"+name);\nreturnname;\n}\n\n@Override\npublicvoidjobToBeExecuted(JobExecutionContextcontext){\nStringjobName=context.getJobDetail().getKey().getName();\nSystem.out.println("Job的名称是:"+jobName+"\\tScheduler在JobDetail将要被执行时调用这个方法");\n}\n\n@Override\npublicvoidjobExecutionVetoed(JobExecutionContextcontext){\nStringjobName=context.getJobDetail().getKey().getName();\nSystem.out.println("Job的名称是:"+jobName+"\\tScheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法");\n}\n\n@Override\npublicvoidjobWasExecuted(JobExecutionContextcontext,JobExecutionExceptionjobException){\nStringjobName=context.getJobDetail().getKey().getName();\nSystem.out.println("Job的名称是:"+jobName+"\\tScheduler在JobDetail被执行之后调用这个方法");\n}\n}\n任务调度类

@Slf4j\npublicclassTestScheduler{\npublicstaticvoidmain(String[]args)throwsException{\n//获取任务调度的实例\nSchedulerscheduler=StdSchedulerFactory.getDefaultScheduler();\n//定义任务调度实例,并与TestJob绑定\nJobDetailjobDetail=JobBuilder.newJob(TestJob.class)\n.usingJobData("executeCount",0)\n.withIdentity("testJob","testJobGroup")\n.build();\n//定义触发器,会马上执行一次,接着5秒执行一次\nTriggertrigger=TriggerBuilder.newTrigger()\n.usingJobData("testInfo","trigger数据存放")\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\n//创建并注册一个全局的JobListener\nscheduler.getListenerManager()\n.addJobListener(newMyJobListener(),\nEverythingMatcher.allJobs());\n\n//使用触发器调度任务的执行\nscheduler.scheduleJob(jobDetail,trigger);\n//开启任务\nscheduler.start();\n}\n}\n/**OUTPUT:\n监听器的名称是:MyJobListener\nJob的名称是:testJobScheduler在JobDetail将要被执行时调用这个方法\nTestJob执行啦\n监听器的名称是:MyJobListener\nJob的名称是:testJobScheduler在JobDetail被执行之后调用这个方法\n**/\n2.TriggerListener

任务调度中,与触发器Trigger相关的事件包括:触发器触发、触发器未正常触发、触发器完成等:

@Slf4j\n@PersistJobDataAfterExecution\npublicclassTestJobimplementsJob{\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nSystem.out.println("TestJob执行啦");\n}\n}\nTriggerListener:

publicclassMyTriggerListenerimplementsTriggerListener{\nprivateStringname;\n\npublicMyTriggerListener(Stringname){\nthis.name=name;\n}\n\n@Override\npublicStringgetName(){\nreturnname;\n}\n\n@Override\npublicvoidtriggerFired(Triggertrigger,JobExecutionContextcontext){\nStringtriggerName=trigger.getKey().getName();\nSystem.out.println(triggerName+"被触发");\n}\n\n@Override\npublicbooleanvetoJobExecution(Triggertrigger,JobExecutionContextcontext){\nStringtriggerName=trigger.getKey().getName();\nSystem.out.println(triggerName+"没有被触发");\nreturnfalse;//true:表示不会执行Job的方法\n}\n\n@Override\npublicvoidtriggerMisfired(Triggertrigger){\nStringtriggerName=trigger.getKey().getName();\nSystem.out.println(triggerName+"错过触发");\n}\n\n@Override\npublicvoidtriggerComplete(Triggertrigger,JobExecutionContextjobExecutionContext,Trigger.CompletedExecutionInstructioncompletedExecutionInstruction){\nStringtriggerName=trigger.getKey().getName();\nSystem.out.println(triggerName+"完成之后触发");\n}\n\n}\n任务调度类:

@Slf4j\npublicclassTestScheduler{\npublicstaticvoidmain(String[]args)throwsException{\n//获取任务调度的实例\nSchedulerscheduler=StdSchedulerFactory.getDefaultScheduler();\n//定义任务调度实例,并与TestJob绑定\nJobDetailjobDetail=JobBuilder.newJob(TestJob.class)\n.usingJobData("executeCount",0)\n.withIdentity("testJob","testJobGroup")\n.build();\n//定义触发器,会马上执行一次,接着5秒执行一次\nTriggertrigger=TriggerBuilder.newTrigger()\n.usingJobData("testInfo","trigger数据存放")\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\n\n//创建并注册一个全局的TriggerListener\nscheduler.getListenerManager().addTriggerListener(newMyTriggerListener("simpleTrigger"),EverythingMatcher.allTriggers());\n\n//使用触发器调度任务的执行\nscheduler.scheduleJob(jobDetail,trigger);\n//开启任务\nscheduler.start();\n}\n}\n/**OUTPUT:\ntestTrigger被触发\ntestTrigger没有被触发\nTestJob执行啦\ntestTrigger完成之后触发\n**/\n3.SchedulerListener

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

@Slf4j\n@PersistJobDataAfterExecution\npublicclassTestJobimplementsJob{\n\n@Override\npublicvoidexecute(JobExecutionContextjobExecutionContext){\nSystem.out.println("TestJob执行啦");\n}\n}\nSchedulerListener:

publicclassMySchedulerListenerimplementsSchedulerListener{\n@Override\npublicvoidjobScheduled(Triggertrigger){\nStringjobName=trigger.getJobKey().getName();\nSystem.out.println(jobName+"完成部署");\n}\n\n@Override\npublicvoidjobUnscheduled(TriggerKeytriggerKey){\nSystem.out.println(triggerKey+"完成卸载");\n}\n\n@Override\npublicvoidtriggerFinalized(Triggertrigger){\nSystem.out.println("触发器被移除"+trigger.getJobKey().getName());\n}\n\n@Override\npublicvoidtriggerPaused(TriggerKeytriggerKey){\nSystem.out.println(triggerKey+"正在被暂停");\n}\n\n@Override\npublicvoidtriggersPaused(StringtriggerGroup){\nSystem.out.println("触发器组"+triggerGroup+"正在被暂停");\n}\n\n@Override\npublicvoidtriggerResumed(TriggerKeytriggerKey){\nSystem.out.println(triggerKey+"正在从暂停中恢复");\n}\n\n@Override\npublicvoidtriggersResumed(StringtriggerGroup){\nSystem.out.println("触发器组"+triggerGroup+"正在从暂停中恢复");\n}\n\n@Override\npublicvoidjobAdded(JobDetailjobDetail){\nSystem.out.println(jobDetail.getKey()+"添加工作任务");\n}\n\n@Override\npublicvoidjobDeleted(JobKeyjobKey){\nSystem.out.println(jobKey+"删除工作任务");\n}\n\n@Override\npublicvoidjobPaused(JobKeyjobKey){\nSystem.out.println(jobKey+"工作任务正在被暂停");\n}\n\n@Override\npublicvoidjobsPaused(StringjobGroup){\nSystem.out.println("工作任务组"+jobGroup+"正在被暂停");\n}\n\n@Override\npublicvoidjobResumed(JobKeyjobKey){\nSystem.out.println(jobKey+"正在从暂停中恢复");\n}\n\n@Override\npublicvoidjobsResumed(StringjobGroup){\nSystem.out.println("工作任务组"+jobGroup+"正在从暂停中恢复");\n}\n\n@Override\npublicvoidschedulerError(Stringmsg,SchedulerExceptioncause){\nSystem.out.println("产生严重错误时调用:"+msg+""+cause.getUnderlyingException());\n}\n\n@Override\npublicvoidschedulerInStandbyMode(){\nSystem.out.println("调度器在挂起模式下调用");\n}\n\n@Override\npublicvoidschedulerStarted(){\nSystem.out.println("调度器开启时调用");\n}\n\n@Override\npublicvoidschedulerStarting(){\nSystem.out.println("调度器正在开启时调用");\n}\n\n@Override\npublicvoidschedulerShutdown(){\nSystem.out.println("调度器已经被关闭时调用");\n}\n\n@Override\npublicvoidschedulerShuttingdown(){\nSystem.out.println("调度器正在被关闭时调用");\n}\n\n@Override\npublicvoidschedulingDataCleared(){\nSystem.out.println("调度器的数据被清除时调用");\n}\n}\n任务调度类:

@Slf4j\npublicclassTestScheduler{\npublicstaticvoidmain(String[]args)throwsException{\n//获取任务调度的实例\nSchedulerscheduler=StdSchedulerFactory.getDefaultScheduler();\n//定义任务调度实例,并与TestJob绑定\nJobDetailjobDetail=JobBuilder.newJob(TestJob.class)\n.usingJobData("executeCount",0)\n.withIdentity("testJob","testJobGroup")\n.build();\n//定义触发器,会马上执行一次,接着5秒执行一次\nDateendTime=newDate();\nendTime.setTime(endTime.getTime()+5000);\nTriggertrigger=TriggerBuilder.newTrigger()\n.usingJobData("testInfo","trigger数据存放")\n.withIdentity("testTrigger","testTriggerGroup")\n.startNow()\n.endAt(endTime)//设置了停止时间\n.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))\n.build();\n\n//创建SchedulerListener\nscheduler.getListenerManager().addSchedulerListener(newMySchedulerListener());\n\n//使用触发器调度任务的执行\nscheduler.scheduleJob(jobDetail,trigger);\n//开启任务\nscheduler.start();\n}\n}\n/**OUTPUT:\ntestJobGroup.testJob添加工作任务\ntestJob完成部署\n调度器正在开启时调用\n调度器开启时调用\nTestJob执行啦\n触发器被移除testJob\ntestJobGroup.testJob删除工作任务\n**/\n

通过以上三个监听器的示例,我们也可以大概了解到监听器执行的时机,具体的我们可以实际上手操练一番

这篇Quartz的介绍就告一段落啦,看到这里的你希望有所收获哦!路漫漫,小菜与你一同求索!

END,本文到此结束,如果可以帮助到大家,还望关注本站哦!

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023