电竞比分网-中国电竞赛事及体育赛事平台

分享

SpringBoot2.1-quartz集成yml方式

 wwq圖書世界 2021-06-24

首先非常感謝原作者恒宇少年 ,寫了一遍好文章。找了很多文章終于找到比較有用有價(jià)值的高質(zhì)量博文。

原貼地址:https://www.jianshu.com/p/056281e057b3

以下引用原文章。

在新版本的SpringBoot2.0發(fā)布后,急迫嘗鮮的我將相關(guān)的項(xiàng)目已經(jīng)更換為最新版本,在SpringBoot源碼GitHub看到更新日志,表明了針對(duì)Quartz新版本進(jìn)行了 AutoConfiguration自動(dòng)化配置,省去了很多繁瑣的配置。

官網(wǎng)更新日志

Auto-configuration support is now include for the Quartz Scheduler. We’ve also added a new spring-boot-starter-quartz starter POM.
You can use in-memory JobStores, or a full JDBC-based store. All JobDetail, Calendar and Trigger beans from your Spring application context will be automatically registered with the Scheduler.
For more details read the new "Quartz Scheduler" section of the reference documentation.

SpringBoot2.0版本集成了Quartz2.3.0官網(wǎng)最新版本。

本章目標(biāo)

使用SpringBoot2.0新特性完成Quartz自動(dòng)化配置。

SpringBoot 企業(yè)級(jí)核心技術(shù)學(xué)習(xí)專題


專題專題名稱專題描述
001Spring Boot 核心技術(shù)講解SpringBoot一些企業(yè)級(jí)層面的核心組件
002Spring Boot 核心技術(shù)章節(jié)源碼Spring Boot 核心技術(shù)簡書每一篇文章碼云對(duì)應(yīng)源碼
003Spring Cloud 核心技術(shù)對(duì)Spring Cloud核心技術(shù)全面講解
004Spring Cloud 核心技術(shù)章節(jié)源碼Spring Cloud 核心技術(shù)簡書每一篇文章對(duì)應(yīng)源碼
005QueryDSL 核心技術(shù)全面講解QueryDSL核心技術(shù)以及基于SpringBoot整合SpringDataJPA
006SpringDataJPA 核心技術(shù)全面講解SpringDataJPA核心技術(shù)
007SpringBoot核心技術(shù)學(xué)習(xí)目錄SpringBoot系統(tǒng)的學(xué)習(xí)目錄,敬請(qǐng)關(guān)注點(diǎn)贊??!!

構(gòu)建項(xiàng)目

在前面章節(jié)第四十章:基于SpringBoot & Quartz完成定時(shí)任務(wù)分布式多節(jié)點(diǎn)負(fù)載持久化內(nèi)我們已經(jīng)通過添加配置的方式完成集成,為了本章的方便直接復(fù)制之前的項(xiàng)目,在基礎(chǔ)上進(jìn)行修改。
打開pom.xml配置文件,SpringBoot為我們提供了對(duì)應(yīng)的依賴,我們將之前的quartz相關(guān)依賴刪除,替換為spring-boot-starter-quartz,如下所示:

<!--quartz相關(guān)依賴--><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>${quartz.version}</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>${quartz.version}</version></dependency>>>>>替換為:>>>><!--quartz依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>......

刪除QuartzConfiguration配置類

在之前章節(jié)我們使用QuartzConfiguration配置類來完成了Quartz需要的一系列配置,如:JobFactory、SchedulerFactoryBean等,在我們添加spring-boot-starter-quartz依賴后就不需要主動(dòng)聲明工廠類,因?yàn)?code>spring-boot-starter-quartz已經(jīng)為我們自動(dòng)化配置好了。

自動(dòng)化配置源碼

我們找到IdeaExternal Libraries并且展開spring-boot-autoconfigure-2.0.0.RELEASE.jar,找到org.springframework.boot.autoconfigure.quartz,該目錄就是SpringBoot為我們提供的Quartz自動(dòng)化配置源碼實(shí)現(xiàn),在該目錄下有如下所示幾個(gè)類:

  • AutowireCapableBeanJobFactory
    該類替代了我們之前在QuartzConfiguration配置類的AutowiringSpringBeanJobFactory內(nèi)部類實(shí)現(xiàn),主要作用是我們自定義的QuartzJobBean子類被Spring IOC進(jìn)行托管,可以在定時(shí)任務(wù)類內(nèi)使用注入任意被Spring IOC托管的類。

  • JobStoreType
    該類是一個(gè)枚舉類型,定義了對(duì)應(yīng)application.yml、application.properties文件內(nèi)spring.quartz.job-store-type配置,其目的是配置quartz任務(wù)的數(shù)據(jù)存儲(chǔ)方式,分別為:MEMORY(內(nèi)存方式:默認(rèn))、JDBC(數(shù)據(jù)庫方式)。

  • QuartzAutoConfiguration
    該類是自動(dòng)配置的主類,內(nèi)部配置了SchedulerFactoryBean以及JdbcStoreTypeConfiguration,使用QuartzProperties作為屬性自動(dòng)化配置條件。

  • QuartzDataSourceInitializer
    該類主要用于數(shù)據(jù)源初始化后的一些操作,根據(jù)不同平臺(tái)類型的數(shù)據(jù)庫進(jìn)行選擇不同的數(shù)據(jù)庫腳本。

  • QuartzProperties
    該類對(duì)應(yīng)了spring.quartzapplication.yml、application.properties文件內(nèi)開頭的相關(guān)配置。

  • SchedulerFactoryBeanCustomizer
    這是一個(gè)接口,我們實(shí)現(xiàn)該接口后并且將實(shí)現(xiàn)類使用Spring IOC托管,可以完成SchedulerFactoryBean的個(gè)性化設(shè)置,這里的設(shè)置完全可以對(duì)SchedulerFactoryBean做出全部的設(shè)置變更。

spring.quartz配置

看到QuartzAutoConfiguration類源碼,我們知道了,想要使用自動(dòng)化配置,需要滿足QuartzProperties屬性配置類的初始化,所以我們需要再application.ymlapplication.properties配置文件內(nèi)添加對(duì)應(yīng)的配置信息,如下所示:

spring:quartz:#相關(guān)屬性配置properties:org:quartz:scheduler:instanceName: clusteredSchedulerinstanceId: AUTOjobStore:class: org.quartz.impl.jdbcjobstore.JobStoreTXdriverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegatetablePrefix: QRTZ_isClustered: trueclusterCheckinInterval: 10000useProperties: falsethreadPool:class: org.quartz.simpl.SimpleThreadPoolthreadCount: 10threadPriority: 5threadsInheritContextClassLoaderOfInitializingThread: true#數(shù)據(jù)庫方式j(luò)ob-store-type: jdbc#初始化表結(jié)構(gòu)#jdbc:#initialize-schema: never
  • spring.quartz.properties
    該配置其實(shí)代替了之前的quartz.properties,我們把之前quartz.properties配置文件內(nèi)的所有配置轉(zhuǎn)換成YUML風(fēng)格,對(duì)應(yīng)的添加在該配置下即可,在QuartzAutoConfiguration類內(nèi),會(huì)自動(dòng)調(diào)用SchedulerFactoryBeansetQuartzProperties方法,把spring.quartz.properties內(nèi)的所有配置進(jìn)行設(shè)置。

@Bean@ConditionalOnMissingBeanpublic SchedulerFactoryBean quartzScheduler() {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(this.applicationContext.getAutowireCapableBeanFactory()));// 如果配置了spring.quartz.propertiesif (!this.properties.getProperties().isEmpty()) {//  將所有properties設(shè)置到QuartzPropertiesschedulerFactoryBean.setQuartzProperties(this.asProperties(this.properties.getProperties()));}......省略部分代碼
  • spring.quartz.job-store-type
    設(shè)置quartz任務(wù)的數(shù)據(jù)持久化方式,默認(rèn)是內(nèi)存方式,我們這里沿用之前的方式,配置JDBC以使用數(shù)據(jù)庫方式持久化任務(wù)。

  • spring.quartz.jdbc.initialize-schema

該配置目前版本沒有生效,根據(jù)官網(wǎng)文檔查看,其目的是自動(dòng)將quartz需要的數(shù)據(jù)表通過配置方式進(jìn)行初始化。

測試

  1. 啟動(dòng)項(xiàng)目

  2. 打開瀏覽器訪問http://localhost:8083/good/save?name=abcd&unit=斤&price=12.5進(jìn)行添加定時(shí)任務(wù)

  3. 查看控制臺(tái)輸出

22:55:18.812  INFO 17161 --- [           main] c.hengyu.chapter39.Chapter47Application  : 【【【【【【定時(shí)任務(wù)分布式節(jié)點(diǎn) - quartz-cluster-node-second 已啟動(dòng)】】】】】】2018-03-06 22:55:20.772  INFO 17161 --- [uartzScheduler]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 2 seconds2018-03-06 22:55:20.793  INFO 17161 --- [uartzScheduler]] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_yuqiyudeMacBook-Pro.local1520348117910 started.2018-03-06 22:56:20.103  INFO 17161 --- [nio-8083-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'2018-03-06 22:56:20.103  INFO 17161 --- [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started2018-03-06 22:56:20.121  INFO 17161 --- [nio-8083-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 18 msHibernate: select next_val as id_val from hibernate_sequence for updateHibernate: update hibernate_sequence set next_val= ? where next_val=?Hibernate: insert into basic_good_info (bgi_name, bgi_price, bgi_unit, bgi_id) values (?, ?, ?, ?)2018-03-06 22:56:20.268 TRACE 17161 --- [nio-8083-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [abcd]2018-03-06 22:56:20.269 TRACE 17161 --- [nio-8083-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [NUMERIC] - [12.5]2018-03-06 22:56:20.269 TRACE 17161 --- [nio-8083-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [VARCHAR] - [斤]2018-03-06 22:56:20.269 TRACE 17161 --- [nio-8083-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [BIGINT] - [1]2018-03-06 22:56:47.253  INFO 17161 --- [eduler_Worker-1] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Tue Mar 06 22:56:47 CST 20182018-03-06 22:57:00.012  INFO 17161 --- [eduler_Worker-2] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Tue Mar 06 22:57:00 CST 20182018-03-06 22:57:20.207  INFO 17161 --- [eduler_Worker-3] c.hengyu.chapter39.timers.GoodAddTimer   : 分布式節(jié)點(diǎn)quartz-cluster-node-second,商品添加完成后執(zhí)行任務(wù),任務(wù)時(shí)間:Tue Mar 06 22:57:20 CST 20182018-03-06 22:57:30.013  INFO 17161 --- [eduler_Worker-4] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Tue Mar 06 22:57:30 CST 20182018-03-06 22:58:00.014  INFO 17161 --- [eduler_Worker-5] c.h.c.timers.GoodStockCheckTimer         : 分布式節(jié)點(diǎn)quartz-cluster-node-second,執(zhí)行庫存檢查定時(shí)任務(wù),執(zhí)行時(shí)間:Tue Mar 06 22:58:00 CST 2018

根據(jù)控制臺(tái)內(nèi)容,可以看到我們的定時(shí)任務(wù)已經(jīng)正常的開始執(zhí)行,當(dāng)然我們?nèi)绻蜷_多個(gè)節(jié)點(diǎn)同樣可以實(shí)現(xiàn)任務(wù)自動(dòng)漂移的效果。

總結(jié)

綜上所述我們已經(jīng)完成了SpringBoot2.0集成Quartz,我們只需要添加依賴、添加配置即可,別的不需要做任何代碼編寫。



作者:恒宇少年
鏈接:https://www.jianshu.com/p/056281e057b3
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)注明出處。

我來說說我自己的背景

springboot 2.1.0版本 

同樣也是集成了quartz的2.3.0版本

我的yml配置

    這里我已經(jīng)是通過了持久化的測試,在2.0往后的quartz的集成中,是不需要讓你去再配datasourse的。之前看了幾篇文章,各種在properties中配自定義的datasourse,然后配置驅(qū)動(dòng)什么的。按照那種方式的配置應(yīng)該也是在spring boot1.5中的做法。

    我這里把jobStore和job-store-type注釋掉的原因是因?yàn)?,我在開發(fā)環(huán)境下我是希望我每次重新啟動(dòng)項(xiàng)目的時(shí)候job都可以在執(zhí)行的時(shí)候重新的執(zhí)行第一次,因?yàn)槲沂且績蓚€(gè)小時(shí)獲取微信的AccessToken的場景下面,如果是持久化到數(shù)據(jù)庫的話

    比如定時(shí)7200秒執(zhí)行一次,現(xiàn)在時(shí)間是中午12點(diǎn),他就會(huì)在你這個(gè)啟動(dòng)的時(shí)間去執(zhí)行一次,然后下次的執(zhí)行時(shí)間是下午2點(diǎn)。在12-2點(diǎn)的時(shí)間內(nèi)不管你項(xiàng)目怎么啟動(dòng) 他都不會(huì)重復(fù)的去執(zhí)行,他只認(rèn)2點(diǎn)鐘這個(gè)時(shí)間點(diǎn)執(zhí)行。

     再比如你是在開發(fā)中1點(diǎn)50分的時(shí)候關(guān)閉了程序,沒有啟動(dòng),而你在2點(diǎn)零1分的時(shí)候啟動(dòng)了項(xiàng)目,那么你啟動(dòng)這個(gè)項(xiàng)目的時(shí)候也是不會(huì)幫你去執(zhí)行任務(wù)的,因?yàn)樗徽J(rèn)2點(diǎn)鐘的時(shí)候,2點(diǎn)的時(shí)候你程序沒有啟動(dòng),所以他不會(huì)幫你重新的回過頭,對(duì)于任務(wù)來說那么下次的執(zhí)行時(shí)間就是下午4點(diǎn)鐘。你要想任務(wù)式執(zhí)行的那么你就要保持服務(wù)是開啟的。

 所以我在開發(fā)環(huán)境下面把持久化到數(shù)據(jù)庫的配置先注釋掉,保存在內(nèi)存中,這樣每次項(xiàng)目啟動(dòng)的時(shí)候都能保證任務(wù)執(zhí)行一次。適合項(xiàng)目在初始化的時(shí)候就需要執(zhí)行任務(wù)的場景。到了生產(chǎn)環(huán)境下面的話就可以換成持久化的。

因?yàn)樵髡邔?duì)配置的東西講的已經(jīng)比較詳細(xì)了,我就不過多說了,我最后會(huì)貼上sql語句,只要是配置好了你的datasourse不需要再quartz中再次配置了,就可以自動(dòng)成功持久化數(shù)據(jù)庫了。

我就在貼出一下 需要用到和我一樣需求的在項(xiàng)目初始化的時(shí)候就開始執(zhí)行的一種方式。

  • 方式一:使用cron表達(dá)式來創(chuàng)建任務(wù)。(不建議在開發(fā)環(huán)境中使用)

package com.atao.zowei.job;import com.atao.zowei.util.QuartzManager;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class InitializationJobManage {//    @Autowired//    QuartzManager quartzManager;/*** 持久化在數(shù)據(jù)庫的時(shí)候用cron表達(dá)式的話,jobName是不能重復(fù)的,在正式服務(wù)器環(huán)境下可以使用這種方式,在開發(fā)環(huán)境下建議使用simpleSchedule*///    @Bean//    public void Initialization(){//        quartzManager.addJob(WeiXinAccessTokenJob.class.getName(),WeiXinAccessTokenJob.class,"0 0 0/2 * * ? ");//    }}

下面貼上我修改過的封裝好的適合springboot使用的 quartz的工具類

在工具類中使用作者的方法自動(dòng)注入了Scheduler調(diào)度器??梢詫?shí)現(xiàn)任務(wù)的增加,修改,停止,移除。

package com.atao.zowei.util;import java.util.Map;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDetail;import org.quartz.JobKey;import org.quartz.Scheduler;import org.quartz.TriggerBuilder;import org.quartz.TriggerKey;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;/*** 定時(shí)任務(wù)管理類** @author ataopro* @editdate 2018-11-30*/@Componentpublic class QuartzManager {/*** 注入任務(wù)調(diào)度器*/@Autowiredprivate Scheduler sched;private static String JOB_GROUP_NAME = "ATAO_JOBGROUP";                    //任務(wù)組private static String TRIGGER_GROUP_NAME = "ATAO_TRIGGERGROUP";            //觸發(fā)器組/*** 添加一個(gè)定時(shí)任務(wù),使用默認(rèn)的任務(wù)組名,觸發(fā)器名,觸發(fā)器組名** @param jobName 任務(wù)名* @param cls     任務(wù)* @param time    時(shí)間設(shè)置,參考quartz說明文檔*/public void addJob(String jobName, Class<? extends Job> cls, String time) {try {JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();    //用于描敘Job實(shí)現(xiàn)類及其他的一些靜態(tài)信息,構(gòu)建一個(gè)作業(yè)實(shí)例CronTrigger trigger = TriggerBuilder.newTrigger()                                                                        //創(chuàng)建一個(gè)新的TriggerBuilder來規(guī)范一個(gè)觸發(fā)器.withIdentity(jobName, TRIGGER_GROUP_NAME)                                            //給觸發(fā)器起一個(gè)名字和組名.withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start();      // 啟動(dòng)}} catch (Exception e) {throw new RuntimeException(e);}}/*** 添加一個(gè)定時(shí)任務(wù),使用默認(rèn)的任務(wù)組名,觸發(fā)器名,觸發(fā)器組名  (帶參數(shù))** @param jobName 任務(wù)名* @param cls     任務(wù)* @param time    時(shí)間設(shè)置,參考quartz說明文檔*/public void addJob(String jobName, Class<? extends Job> cls, String time, Map<String, Object> parameter) {try {JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();    //用于描敘Job實(shí)現(xiàn)類及其他的一些靜態(tài)信息,構(gòu)建一個(gè)作業(yè)實(shí)例jobDetail.getJobDataMap().put("parameterList", parameter);                                    //傳參數(shù)CronTrigger trigger = TriggerBuilder.newTrigger()                                                                        //創(chuàng)建一個(gè)新的TriggerBuilder來規(guī)范一個(gè)觸發(fā)器.withIdentity(jobName, TRIGGER_GROUP_NAME)                                            //給觸發(fā)器起一個(gè)名字和組名.withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start();      // 啟動(dòng)}} catch (Exception e) {throw new RuntimeException(e);}}/*** 添加一個(gè)定時(shí)任務(wù)** @param jobName          任務(wù)名* @param jobGroupName     任務(wù)組名* @param triggerName      觸發(fā)器名* @param triggerGroupName 觸發(fā)器組名* @param jobClass         任務(wù)* @param time             時(shí)間設(shè)置,參考quartz說明文檔*/public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class<? extends Job> jobClass,String time) {try {JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();// 任務(wù)名,任務(wù)組,任務(wù)執(zhí)行類CronTrigger trigger = TriggerBuilder     // 觸發(fā)器.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start();      // 啟動(dòng)}} catch (Exception e) {throw new RuntimeException(e);}}/*** 添加一個(gè)定時(shí)任務(wù)  (帶參數(shù))** @param jobName          任務(wù)名* @param jobGroupName     任務(wù)組名* @param triggerName      觸發(fā)器名* @param triggerGroupName 觸發(fā)器組名* @param jobClass         任務(wù)* @param time             時(shí)間設(shè)置,參考quartz說明文檔*/public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class<? extends Job> jobClass,String time, Map<String, Object> parameter) {try {JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();// 任務(wù)名,任務(wù)組,任務(wù)執(zhí)行類jobDetail.getJobDataMap().put("parameterList", parameter);                                //傳參數(shù)CronTrigger trigger =  TriggerBuilder     // 觸發(fā)器.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start();      // 啟動(dòng)}} catch (Exception e) {throw new RuntimeException(e);}}/*** 修改一個(gè)任務(wù)的觸發(fā)時(shí)間(使用默認(rèn)的任務(wù)組名,觸發(fā)器名,觸發(fā)器組名)** @param jobName 任務(wù)名* @param time    新的時(shí)間設(shè)置*/public void modifyJobTime(String jobName, String time) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);        //通過觸發(fā)器名和組名獲取TriggerKeyCronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);                //通過TriggerKey獲取CronTriggerif (trigger == null) {return;}String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);                        //通過任務(wù)名和組名獲取JobKeyJobDetail jobDetail = sched.getJobDetail(jobKey);Class<? extends Job> objJobClass = jobDetail.getJobClass();removeJob(jobName);addJob(jobName, objJobClass, time);}} catch (Exception e) {throw new RuntimeException(e);}}/*** 修改一個(gè)任務(wù)的觸發(fā)時(shí)間** @param triggerName      任務(wù)名稱* @param triggerGroupName 傳過來的任務(wù)名稱* @param time             更新后的時(shí)間規(guī)則*/public void modifyJobTime(String triggerName, String triggerGroupName, String time) {try {TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);    //通過觸發(fā)器名和組名獲取TriggerKeyCronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);                //通過TriggerKey獲取CronTriggerif (trigger == null) return;CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(trigger.getCronExpression());String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {trigger = (CronTrigger) trigger.getTriggerBuilder()        //重新構(gòu)建trigger.withIdentity(triggerKey).withSchedule(scheduleBuilder).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.rescheduleJob(triggerKey, trigger);                //按新的trigger重新設(shè)置job執(zhí)行}} catch (Exception e) {throw new RuntimeException(e);}}/*** 移除一個(gè)任務(wù)(使用默認(rèn)的任務(wù)組名,觸發(fā)器名,觸發(fā)器組名)** @param jobName 任務(wù)名稱*/public void removeJob(String jobName) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);    //通過觸發(fā)器名和組名獲取TriggerKeyJobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);                        //通過任務(wù)名和組名獲取JobKeysched.pauseTrigger(triggerKey);    // 停止觸發(fā)器sched.unscheduleJob(triggerKey);// 移除觸發(fā)器sched.deleteJob(jobKey);        // 刪除任務(wù)} catch (Exception e) {throw new RuntimeException(e);}}/*** 移除一個(gè)任務(wù)** @param jobName          任務(wù)名* @param jobGroupName     任務(wù)組名* @param triggerName      觸發(fā)器名* @param triggerGroupName 觸發(fā)器組名*/public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {try {TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);    //通過觸發(fā)器名和組名獲取TriggerKeyJobKey jobKey = JobKey.jobKey(jobName, jobGroupName);                            //通過任務(wù)名和組名獲取JobKeysched.pauseTrigger(triggerKey);    // 停止觸發(fā)器sched.unscheduleJob(triggerKey);// 移除觸發(fā)器sched.deleteJob(jobKey);        // 刪除任務(wù)} catch (Exception e) {throw new RuntimeException(e);}}/*** 啟動(dòng)所有定時(shí)任務(wù)*/public void startJobs() {try {sched.start();} catch (Exception e) {throw new RuntimeException(e);}}/*** 關(guān)閉所有定時(shí)任務(wù)*/public void shutdownJobs() {try {if (!sched.isShutdown()) {sched.shutdown();}} catch (Exception e) {throw new RuntimeException(e);}}}

 http://cron./ 這個(gè)是自動(dòng)生成cron表達(dá)式的工具網(wǎng)址。

  • 方式二

使用simpleSchedule來添加任務(wù)。

package com.atao.zowei.job;import org.quartz.*;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class QuartzConfig {/*** 定時(shí)獲取AccessToken保存到redis中* @return*/@Beanpublic JobDetail getWeiXinAccessTokenQuartzDetail(){return JobBuilder.newJob(WeiXinAccessTokenJob.class).withIdentity("getWeiXinAccessTokenQuartz").storeDurably().build();}@Beanpublic Trigger getWeiXinAccessTokenTrigger(){SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(7200)  //設(shè)置時(shí)間周期單位秒.repeatForever();return TriggerBuilder.newTrigger().forJob(getWeiXinAccessTokenQuartzDetail()).withIdentity("getWeiXinAccessTokenQuartz").withSchedule(scheduleBuilder).build();}}

下面說下使用simpleSchedule創(chuàng)建job和Scheduler創(chuàng)建job的區(qū)別

其實(shí)我研究也不是很深入,我只能講到我遇到的問題。

  • 在使用持久化到數(shù)據(jù)庫的時(shí)候使用simpleSchedule創(chuàng)建的任務(wù)式可以重復(fù)創(chuàng)建的就是說你在開發(fā)環(huán)境下的話難免會(huì)重啟服務(wù),使用simpleSchedule的方式的話會(huì)覆蓋持久化在數(shù)據(jù)庫中的job記錄。

  • 而使用Scheduler配合cron表達(dá)式的方式創(chuàng)建的,他需要你又任務(wù)組名和任務(wù)名,然后你的任務(wù)名是不能重復(fù)的創(chuàng)建的,就是說如果在開發(fā)環(huán)境下使用了這種方式,你重啟了服務(wù)或者你重復(fù)的添加了這個(gè)任務(wù),任務(wù)名重復(fù)的話,系統(tǒng)則會(huì)報(bào)錯(cuò),你不會(huì)像每次啟動(dòng)服務(wù)的時(shí)候都去換一個(gè)任務(wù)名的,當(dāng)然也有直接用UUID當(dāng)任務(wù)名的,但是我個(gè)人建議的話還是使用class的name比較好?;蛘吣闳グ褦?shù)據(jù)庫的表重新構(gòu)建一遍清空數(shù)據(jù)表。

  我就在這上面踩了雷,我就一直重復(fù)的去啟動(dòng)項(xiàng)目,然后第一次是成功的,第二次就不行了。所以這邊點(diǎn)的話注意一下。

貼上建表的sql語句

/*Navicat MySQL Data TransferSource Server         : localSource Server Version : 50505Source Host           : localhost:3306Source Database       : quartzTarget Server Type    : MYSQLTarget Server Version : 50505File Encoding         : 65001Date: 2017-11-05 18:01:51*/SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for qrtz_blob_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_blob_triggers`;CREATE TABLE `qrtz_blob_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`BLOB_DATA` blob DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_calendars-- ----------------------------DROP TABLE IF EXISTS `qrtz_calendars`;CREATE TABLE `qrtz_calendars` (`SCHED_NAME` varchar(120) NOT NULL,`CALENDAR_NAME` varchar(200) NOT NULL,`CALENDAR` blob NOT NULL,PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_cron_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_cron_triggers`;CREATE TABLE `qrtz_cron_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`CRON_EXPRESSION` varchar(120) NOT NULL,`TIME_ZONE_ID` varchar(80) DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_fired_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_fired_triggers`;CREATE TABLE `qrtz_fired_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`ENTRY_ID` varchar(95) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`INSTANCE_NAME` varchar(200) NOT NULL,`FIRED_TIME` bigint(13) NOT NULL,`SCHED_TIME` bigint(13) NOT NULL,`PRIORITY` int(11) NOT NULL,`STATE` varchar(16) NOT NULL,`JOB_NAME` varchar(200) DEFAULT NULL,`JOB_GROUP` varchar(200) DEFAULT NULL,`IS_NONCONCURRENT` varchar(1) DEFAULT NULL,`REQUESTS_RECOVERY` varchar(1) DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`),KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`),KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`),KEY `IDX_QRTZ_FT_J_G` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_job_details-- ----------------------------DROP TABLE IF EXISTS `qrtz_job_details`;CREATE TABLE `qrtz_job_details` (`SCHED_NAME` varchar(120) NOT NULL,`JOB_NAME` varchar(200) NOT NULL,`JOB_GROUP` varchar(200) NOT NULL,`DESCRIPTION` varchar(250) DEFAULT NULL,`JOB_CLASS_NAME` varchar(250) NOT NULL,`IS_DURABLE` varchar(1) NOT NULL,`IS_NONCONCURRENT` varchar(1) NOT NULL,`IS_UPDATE_DATA` varchar(1) NOT NULL,`REQUESTS_RECOVERY` varchar(1) NOT NULL,`JOB_DATA` blob DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`),KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_locks-- ----------------------------DROP TABLE IF EXISTS `qrtz_locks`;CREATE TABLE `qrtz_locks` (`SCHED_NAME` varchar(120) NOT NULL,`LOCK_NAME` varchar(40) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_paused_trigger_grps-- ----------------------------DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`;CREATE TABLE `qrtz_paused_trigger_grps` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_scheduler_state-- ----------------------------DROP TABLE IF EXISTS `qrtz_scheduler_state`;CREATE TABLE `qrtz_scheduler_state` (`SCHED_NAME` varchar(120) NOT NULL,`INSTANCE_NAME` varchar(200) NOT NULL,`LAST_CHECKIN_TIME` bigint(13) NOT NULL,`CHECKIN_INTERVAL` bigint(13) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_simple_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_simple_triggers`;CREATE TABLE `qrtz_simple_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`REPEAT_COUNT` bigint(7) NOT NULL,`REPEAT_INTERVAL` bigint(12) NOT NULL,`TIMES_TRIGGERED` bigint(10) NOT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_simprop_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_simprop_triggers`;CREATE TABLE `qrtz_simprop_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`STR_PROP_1` varchar(512) DEFAULT NULL,`STR_PROP_2` varchar(512) DEFAULT NULL,`STR_PROP_3` varchar(512) DEFAULT NULL,`INT_PROP_1` int(11) DEFAULT NULL,`INT_PROP_2` int(11) DEFAULT NULL,`LONG_PROP_1` bigint(20) DEFAULT NULL,`LONG_PROP_2` bigint(20) DEFAULT NULL,`DEC_PROP_1` decimal(13,4) DEFAULT NULL,`DEC_PROP_2` decimal(13,4) DEFAULT NULL,`BOOL_PROP_1` varchar(1) DEFAULT NULL,`BOOL_PROP_2` varchar(1) DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ------------------------------ Table structure for qrtz_triggers-- ----------------------------DROP TABLE IF EXISTS `qrtz_triggers`;CREATE TABLE `qrtz_triggers` (`SCHED_NAME` varchar(120) NOT NULL,`TRIGGER_NAME` varchar(200) NOT NULL,`TRIGGER_GROUP` varchar(200) NOT NULL,`JOB_NAME` varchar(200) NOT NULL,`JOB_GROUP` varchar(200) NOT NULL,`DESCRIPTION` varchar(250) DEFAULT NULL,`NEXT_FIRE_TIME` bigint(13) DEFAULT NULL,`PREV_FIRE_TIME` bigint(13) DEFAULT NULL,`PRIORITY` int(11) DEFAULT NULL,`TRIGGER_STATE` varchar(16) NOT NULL,`TRIGGER_TYPE` varchar(8) NOT NULL,`START_TIME` bigint(13) NOT NULL,`END_TIME` bigint(13) DEFAULT NULL,`CALENDAR_NAME` varchar(200) DEFAULT NULL,`MISFIRE_INSTR` smallint(2) DEFAULT NULL,`JOB_DATA` blob DEFAULT NULL,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),KEY `IDX_QRTZ_T_J` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_T_JG` (`SCHED_NAME`,`JOB_GROUP`),KEY `IDX_QRTZ_T_C` (`SCHED_NAME`,`CALENDAR_NAME`),KEY `IDX_QRTZ_T_G` (`SCHED_NAME`,`TRIGGER_GROUP`),KEY `IDX_QRTZ_T_STATE` (`SCHED_NAME`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_N_STATE` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_N_G_STATE` (`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_NEXT_FIRE_TIME` (`SCHED_NAME`,`NEXT_FIRE_TIME`),KEY `IDX_QRTZ_T_NFT_ST` (`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`),KEY `IDX_QRTZ_T_NFT_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`),KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`),KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

最后還是在提一下cron表達(dá)式吧

上面的話你選完條件了,看下面的。就只要記得cron表達(dá)式 下面的運(yùn)行時(shí)間就是馬上任務(wù)執(zhí)行的時(shí)間節(jié)點(diǎn)。

他只認(rèn)絕對(duì)的時(shí)間,就是在下面的那個(gè)時(shí)間點(diǎn)的時(shí)候會(huì)去執(zhí)行,別的時(shí)間不會(huì)去執(zhí)行

至于是到底怎么寫還是別去深究了,就看下面給你的運(yùn)行時(shí)間,就是那個(gè)時(shí)間節(jié)點(diǎn)就行了,拋開以前那些什么相對(duì)時(shí)間,從現(xiàn)在開始多久執(zhí)行一次,他就是固定的時(shí)間點(diǎn),都是如此。好了,現(xiàn)在就想到這么多。對(duì)于查詢sql數(shù)據(jù)庫什么的到時(shí)候研究出來的再來補(bǔ)充。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多