javascript
SpringBoot整合Quartz--使用/教程/实例
原文網址:SpringBoot整合Quartz--使用/教程/實例_IT利刃出鞘的博客-CSDN博客
簡介
說明
? ? ? ? 本文用實例介紹quartz的用法。
? ? ? ? quartz與spring自帶的定時最大的區別之處:quartz可以用Calendar來控制哪些時間不執行此定時任務。
Job
- 是一個接口,只定義一個方法 execute(JobExecutionContext context),在實現接口的execute 方法中編寫所需要定時執行的 Job(任務);
- Job接口是真正需要執行的任務,Quartz 每次調度 Job 時,都重新創建一個 Job 實例,因此它不接受多個 Job 的實例。
- JobExecutionContext 類提供了調度應用的一些信息;
- Job 運行時的信息保存在 JobDataMap 實例中。
JobDetail
JobDetail接口相當于將Job接口包裝了一下,Trigger和Scheduler實際用到的都是JobDetail。
。它接收一個 Job 實現類(JobDetail,描述 Job 的實現類及其他相關的靜態信息,如 Job 名字、描述、關聯監聽器等信息),以便運行時通過 newInstance() 的反射機制實例化 Job。
Trigger接口
觸發器,描述觸發 Job 的時間觸發規則,主要有 SimpleTrigger 和 CronTrigger 這兩個實現類。系統時間走到觸發器指定的時間的時候,觸發器就會觸發任務的執行。
Scheduler接口
- 調度器,Quartz通過調度器來注冊、暫停、刪除Trigger和JobDetail。
- Trigger 和 JobDetail 可以注冊到 Scheduler 中,兩者在 Scheduler 中擁有各自的組及名稱。組及名稱是 Scheduler 查找定位容器中某一對象的依據, Trigger 的組及名稱必須唯一, JobDetail 的組和名稱也必須唯一(但可以和 Trigger 的組和名稱相同,因為它們是不同類型的)。
- Scheduler 定義了多個接口方法,允許外部通過組及名稱訪問和控制容器中 Trigger 和JobDetail(是通過SchedulerContext獲得的)。
Calendar接口
一個Trigger可以和多個Calendar關聯,以便排除或包含某些時間點。例如:每周星期一早上10:00執行任務,但是如果碰到法定的節日,則不執行,這時就需要在Trigger觸發機制的基礎上使用Calendar進行定點排除。
Calendar有如下實現類:
基礎實例
其他網址
SpringBoot 集成 Quartz 定時器_真的愿意去努力,人生最壞的結果,也不過是大器晚成。-CSDN博客
Spring Boot-Quartz框架_小草帽的博客-CSDN博客
簡介
有的博客里邊說需要@EnableScheduling,經本人測試并不需要。
依賴
? ? ? ? 如果SpringBoot版本是2.0.0以后的,則在spring-boot-starter中已經包含了quart的依賴,則可以直接使用spring-boot-starter-quartz依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId> </dependency>如果是1.5.9則要使用以下添加依賴:
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId> </dependency>?本處為了測試,還引入了swagger和web依賴。其相關依賴以及如何使能本處就不寫了。
任務
任務1
package com.example.demo.schedule;import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException;import java.text.SimpleDateFormat; import java.util.Date;public class Job1 implements Job {private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");private void before() {System.out.println("任務1:開始執行-" + dateFormat.format(new Date()));}@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {before();System.out.println("任務1:業務邏輯。。。");after();}private void after() {System.out.println("任務1:執行結束");System.out.println();} }任務2
package com.example.demo.schedule;import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException;import java.text.SimpleDateFormat; import java.util.Date;public class Job2 implements Job {private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");private void before() {System.out.println("任務2:開始執行-" + dateFormat.format(new Date()));}@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {before();System.out.println("任務2:業務邏輯。。。");after();}private void after() {System.out.println("任務2:執行結束");System.out.println();} }工具類
package com.example.demo.util;import com.example.demo.schedule.Job1; import com.example.demo.schedule.Job2; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;import java.util.Date;@Component public class QuartzSchedulerManager {@Autowiredprivate Scheduler scheduler;// 開始執行定時器public void startJob() throws SchedulerException {startJob1(scheduler);startJob2(scheduler);scheduler.start();}// 獲取Job信息public String getJobInfo(String name, String group) throws SchedulerException {TriggerKey triggerKey = new TriggerKey(name, group);CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),scheduler.getTriggerState(triggerKey).name());}// 修改某個任務的執行時間public boolean modifyJob(String name, String group, String time) throws SchedulerException {Date date = null;TriggerKey triggerKey = new TriggerKey(name, group);CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);String oldTime = cronTrigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group).withSchedule(cronScheduleBuilder).build();date = scheduler.rescheduleJob(triggerKey, trigger);}return date != null;}// 暫停所有任務public void pauseAllJob() throws SchedulerException {scheduler.pauseAll();}// 暫停某個任務public void pauseJob(String name, String group) throws SchedulerException {JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.pauseJob(jobKey);}// 恢復所有任務public void resumeAllJob() throws SchedulerException {scheduler.resumeAll();}// 恢復某個任務public void resumeJob(String name, String group) throws SchedulerException {JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.resumeJob(jobKey);}// 刪除某個任務public void deleteJob(String name, String group) throws SchedulerException {JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.deleteJob(jobKey);}// 啟動任務1private void startJob1(Scheduler scheduler) throws SchedulerException {// 通過JobBuilder構建JobDetail實例,JobDetail規定其job只能是實現Job接口的實例JobDetail jobDetail = JobBuilder.newJob(Job1.class).withIdentity("job1", "group1").build();// 基于表達式構建觸發器CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");// CronTrigger表達式觸發器 繼承于Trigger。TriggerBuilder 用于構建觸發器實例CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1").withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);}// 啟動任務2private void startJob2(Scheduler scheduler) throws SchedulerException {// 通過JobBuilder構建JobDetail實例,JobDetail規定其job只能是實現Job接口的實例JobDetail jobDetail = JobBuilder.newJob(Job2.class).withIdentity("job2", "group2").build();// 基于表達式構建觸發器CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");// CronTrigger表達式觸發器 繼承于Trigger。TriggerBuilder 用于構建觸發器實例CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2").withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);} }說明
TriggerBuilder.newTrigger().withIdentity()有三個重載:
 ? ??withIdentity(String name, String group)
 ? ??withIdentity(String name)? //內部調用new TriggerKey(name, null)
 ? ??withIdentity(TriggerKey triggerKey)
服務啟動時運行
package com.example.demo.config;import com.example.demo.util.QuartzSchedulerManager; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ContextRefreshedEvent;@Configuration public class QuartzListener implements ApplicationListener<ContextRefreshedEvent> {@Autowiredprivate QuartzSchedulerManager quartzSchedulerManager;// 初始啟動quartz@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {try {quartzSchedulerManager.startJob();System.out.println("任務已經啟動...");} catch (SchedulerException e) {e.printStackTrace();}}// 初始注入scheduler@Beanpublic Scheduler scheduler() throws SchedulerException{SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();return schedulerFactoryBean.getScheduler(); } }控制器
注意:Quartz提供了一個驗證cron是否合法的方法:CronExpression.isValidExpression(String cron);
package com.example.demo.controller; import com.example.demo.util.QuartzSchedulerManager; import org.quartz.CronExpression; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("") public class QuartzController {@Autowiredprivate QuartzSchedulerManager quartzSchedulerManager;// @Description: 獲取定時器信息@GetMapping("/info")public String getQuartzJob(String name, String group) {String info = null;try {info = quartzSchedulerManager.getJobInfo(name, group);} catch (SchedulerException e) {e.printStackTrace();}return info;}// @Description: 修改定時器的 執行時間@PostMapping("/modify")public boolean modifyQuartzJob(String name, String group, String time) {boolean flag = true;if (!CronExpression.isValidExpression(time)) {throw new RuntimeException("非法的cron表達式");}try {flag = quartzSchedulerManager.modifyJob(name, group, time);} catch (SchedulerException e) {e.printStackTrace();}return flag;}// @Description: 啟動所有定時器@PostMapping("/start")public void startQuartzJob() {try {quartzSchedulerManager.startJob();} catch (SchedulerException e) {e.printStackTrace();}}// @Description: 暫停指定 定時器@PostMapping(value = "/pause")public void pauseQuartzJob(String name, String group) {try {quartzSchedulerManager.pauseJob(name, group);} catch (SchedulerException e) {e.printStackTrace();}}// 暫停所有定時器@PostMapping(value = "/pauseAll")public void pauseAllQuartzJob() {try {quartzSchedulerManager.pauseAllJob();} catch (SchedulerException e) {e.printStackTrace();}}// 刪除指定定時器@PostMapping(value = "/delete")public void deleteJob(String name, String group) {try {quartzSchedulerManager.deleteJob(name, group);} catch (SchedulerException e) {e.printStackTrace();}} }啟動服務
?下邊的交替輸出。
任務1:開始執行-2020-11-04 18:12:20 任務1:業務邏輯。。。 任務1:執行結束任務2:開始執行-2020-11-04 18:12:20 任務2:業務邏輯。。。 任務2:執行結束controller測試?
查看特定任務信息:http://localhost:8080/info?name=job1&group=group1
結果:
time:0/5 * * * * ?,state:NORMALcontroller其他測試都是通過的,本處不再展示。?
Calendar
其他網址
Quartz Scheduler Calendar日歷的使用 - 大新博客 - 博客園
Quartz-Calendar 排除指定節假日時間執行任務_小工匠-CSDN博客
簡介
一個Trigger可以和多個Calendar關聯,以便排除或包含某些時間點。例如:每周星期一早上10:00執行任務,但是如果碰到法定的節日,則不執行,這時就需要在Trigger觸發機制的基礎上使用Calendar進行定點排除。
Calendar有如下實現類:
| Calendar 名稱 | 類 | 用法 | 精度 | 
| BaseCalendar | org.quartz.impl.calendar.BaseCalendar | 為高級的 Calendar 實現了基本的功能,實現了 org.quartz.Calendar 接口 | |
| AnnualCalendar | org.quartz.impl.calendar.AnnualCalendar | 指定年中一天或多天。 | 天 | 
| CronCalendar | org.quartz.impl.calendar.CronCalendar | ? ? 指定CronExpression表達的時間集合。 ? ? 例:“* * 0-7,18-23?* *”排除每天所有營業時間(上午8點至下午5點)。 ? ? 若CronTrigger具有給定的cron表達式并且與具有相同表達式的CronCalendar相關聯,則日歷將排除觸發器包含的所有時間,并且它們將彼此抵消。 | 秒 | 
| DailyCalendar | org.quartz.impl.calendar.DailyCalendar | ? ? ? ? 指定每天營業時間(上午8點 - 5點)。 每個DailyCalendar僅允許指定單個時間范圍,并且該時間范圍可能不會跨越每日邊界(即,您不能指定從上午8點至凌晨5點的時間范圍)。 如果屬性invertTimeRange為false(默認),則時間范圍定義觸發器不允許觸發的時間范圍。 如果invertTimeRange為true,則時間范圍被反轉 - 也就是排除在定義的時間范圍之外的所有時間。 | 毫秒 | 
| HolidayCalendar | org.quartz.impl.calendar.HolidayCalendar | 從 Trigger 中排除/包含節假日 | 天 | 
| MonthlyCalendar | org.quartz.impl.calendar.MonthlyCalendar | 排除/包含月份中的指定數天,例如,可用于排除每月的最后一天 | 天 | 
| WeeklyCalendar | org.quartz.impl.calendar.WeeklyCalendar | 排除/包含星期中的任意周幾,例如,可用于排除周末,默認周六和周日 | 天 | 
實例
說明:下方所有實例,前邊都有
@Autowired
 private Scheduler sched;
AnnualCalendar
This implementation of the Calendar excludes a set of days of the year. You may use it to exclude bank holidays which are on the same date every year @Autowired private Scheduler sched;AnnualCalendar holidays = new AnnualCalendar(); //2014,7,21 實際是2014年8月21日 Calendar calendar = new GregorianCalendar(2014, 7, 21); holidays.setDayExcluded(calendar, true); sched.addCalendar("holidays", holidays, false, false);SimpleTrigger trigger = newTrigger() .withIdentity("trigger1", "group1").startNow().withSchedule(simpleSchedule().withIntervalInHours(1).repeatForever()) .modifiedByCalendar("holidays").build();上邊日歷設置成2014-07-21 并不是只有在2014年才生效,它會在每一年的這個日期都生效?。原因:看計算時間的源碼,并沒有計算設置的年份:
public boolean isDayExcluded(java.util.Calendar day) {...Iterator<java.util.Calendar> iter = excludeDays.iterator();while (iter.hasNext()) {java.util.Calendar cl = (java.util.Calendar) iter.next();// remember, the list is sortedif (dmonth < cl.get(java.util.Calendar.MONTH)) {return false;}if (dday != cl.get(java.util.Calendar.DAY_OF_MONTH)) {continue;}if (dmonth != cl.get(java.util.Calendar.MONTH)) {continue;}return true;}return false; }CronCalendar
This implementation of the Calendar may be used (you don't have to) as a base class for more sophisticated one's.寫一個表達式來排除一個時間范圍,比如可以設置為排除所有的非工作時間:?在早8點-晚5點觸發,其他時間暫停,代碼如下
CronCalendar calendar = new CronCalendar("* * 0-7,18-23 ? * *"); sched.addCalendar("business", calendar, false, false);DailyCalendar
?This implementation of the Calendar excludes (or includes - see below) a specified time range each day. For example, you could use this calendar to exclude business hours (8AM - 5PM) every day. Each DailyCalendar only allows a single time range to be specified, and that time range may not cross daily boundaries (i.e. you cannot specify a time range from 8PM - 5AM). If the property invertTimeRange is false (default), the time range defines a range of times in which triggers are not allowed to fire. If invertTimeRange is true, the time range is inverted – that is, all times outside the defined time range are excluded.Note when using DailyCalendar, it behaves on the same principals as, for example, WeeklyCalendar. WeeklyCalendar defines a set of days that are excluded every week. Likewise, DailyCalendar defines a set of times that are excluded every day.時間范圍日歷,定義一個時間范圍,可以讓觸發器在這個時間范圍內觸發,或者在這個時間范圍內不觸發,每一個DailyCalendar的實例只能設置一次時間范圍,并且這個時間范圍不能超過一天的邊界,比如你不能定義一個時間范圍是(晚上8點至第二天早上5點),如果invertTimeRange這個屬性等于false(默認),那么定義的時間范圍內觸發器不會觸發,相反如果invertTimeRange=true 那么只有在這個時間范圍內觸發器才會觸發,這個時間范圍以外的時間都被排除。
Calendar s = Calendar.getInstance(); s.setTime(new Date());Calendar e = Calendar.getInstance(); e.setTime(futureDate(10, IntervalUnit.SECOND));DailyCalendar dailyCalendar = new DailyCalendar(s, e); //DailyCalendar dailyCalendar = new DailyCalendar("20:57:00", "20:59:00"); dailyCalendar.setInvertTimeRange(true); sched.addCalendar("dailyCalendar", dailyCalendar, false, false); SimpleTrigger trigger = newTrigger() .withIdentity("trigger1", "group1").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(3).repeatForever()).modifiedByCalendar("dailyCalendar").build();HolidayCalendar
This implementation of the Calendar stores a list of holidays (full days that are excluded from scheduling).The implementation DOES take the year into consideration, so if you want to exclude July 4th for the next 10 years, you need to add 10 entries to the exclude list.該日歷與AnnualCalendar一致,區別就是設置的year是有效的,也就是說如果你希望在未來的10年中 7月4日這天 這個日歷生效,那么你需要添加10個日期,分別是 2014-7-4 ,2015-7-4...... 2024-7-4 這樣才行。?
HolidayCalendar holidays = new HolidayCalendar(); Calendar calendar = new GregorianCalendar(2014, 7, 21); holidays.addExcludedDate(calendar.getTime()); sched.addCalendar("holidays", holidays, false, false);MonthlyCalendar
This implementation of the Calendar excludes a set of days of the month. You may use it to exclude every first day of each month for example. But you may define any day of a month.月日歷,你可以定義一個月當中的若干天,例如你可以設置每個月的第一天觸發器不進行觸發,當然你還可以定義一個月當中的任何一天。
下面例子給出每個月2,3,4號不觸發的日歷
MonthlyCalendar monthlyCalendar = new MonthlyCalendar(); monthlyCalendar.setDayExcluded(2, true); monthlyCalendar.setDayExcluded(3, true); monthlyCalendar.setDayExcluded(4, true); sched.addCalendar("monthlyCalendar", monthlyCalendar, false, false);WeeklyCalendar
This implementation of the Calendar excludes a set of days of the week. You may use it to exclude weekends for example. But you may define any day of the week. By default it excludes SATURDAY and SUNDAY.? ? ? ? 星期日歷,可以定義在一個星期當中的星期幾幾幾 是不觸發的日期,例如你可以定義么每個周末(星期天)觸發器不觸發,你也可以定義一周當中的任何一天或是幾天。默認情況SATURDAY ,SUNDAY 這兩天是沒排除的。
? ? ? ? 下面的例子設置了每個星期四觸發器不觸發,并且默認情況周六和周天也是不觸發的,這個是默認設置。如果需要周六周日也觸發,那么把它清掉就可以了(weeklyCalendar.setDayExcluded(Calendar.SATURDAY?, false)像這樣)。一個需要注意的地方就是傳入參數不能直接寫數字星期幾,因為老外的日子計算的與我們不一樣,需要傳入(java.util.Calendar)的常量字段,這樣才準確。
WeeklyCalendar weeklyCalendar = new WeeklyCalendar(); weeklyCalendar.setDayExcluded(Calendar.THURSDAY, true); sched.addCalendar("weeklyCalendar", weeklyCalendar, false, false);組合日歷的使用
? ? ? ? 上面的例子都是每一個觸發器(trigger)關聯一個日歷的例子,我們在構建觸發器的時候通過.modifiedByCalendar("日歷的key")關聯一個注冊到引擎當中的日歷,這種情況已經能夠滿足我們大部分的需求。但是系統的需求往往是復雜多變的,假設有這樣一種情況,需要一個觸發器在 每周一到周五,早8點-晚晚5點 每隔1小時執行,那么該如何使用日歷呢?
? ? ? ? 其實我們不用日歷,使用一個CronTrigger也是可以搞定的,我們這里只不過是拋磚引玉而已。那讓我們來寫一個組合日歷使用的例子:
DailyCalendar dailyCalendar = new DailyCalendar("8:00:00", "17:00:00"); dailyCalendar.setInvertTimeRange(false);WeeklyCalendar weeklyCalendar = new WeeklyCalendar(dailyCalendar); sched.addCalendar("weeklyCalendar", weeklyCalendar, false, false);我們寫一個時間間隔的日歷dailyCalendar,將其作為參數傳遞給weeklyCalendar就可以了,這樣引擎在計算日歷日期的時候會先判斷dailyCalendar的時間范圍,然后再判斷weeklyCalendar是時間范圍,當條件都滿足的是否,觸發器才會被觸發,我們分析一下源碼:
@Override public boolean isTimeIncluded(long timeStamp) {if (excludeAll == true) {return false;}// Test the base calendar first. Only if the base calendar not already// excludes the time/date, continue evaluating this calendar instance.if (super.isTimeIncluded(timeStamp) == false) { return false; }java.util.Calendar cl = createJavaCalendar(timeStamp);int wday = cl.get(java.util.Calendar.DAY_OF_WEEK);return !(isDayExcluded(wday)); }我們發現它首先調用?if (super.isTimeIncluded(timeStamp) == false) { return false; } 奧秘就在這里,我們繼續看。
public boolean isTimeIncluded(long timeStamp) {if (timeStamp <= 0) {throw new IllegalArgumentException("timeStamp must be greater 0");}if (baseCalendar != null) {if (baseCalendar.isTimeIncluded(timeStamp) == false) { return false; }}return true; }這里先判斷了baseCalendar,這個對象就是在構造參數傳遞進去的dailyCalendar , 也就是它先試用dailyCalendar 進行日期計算,然后自己在計算,這樣就完成了日歷的組合使用。
往quartz的引擎中注冊日歷的方法
?addCalendar(String?calName,?Calendar?calendar, boolean?replace, boolean?updateTriggers)?
這個方法有四個參數
1、calName 日歷的名字,在構建觸發器時通過modifiedByCalendar("")這里使用。
 2、calendar 日歷對象。
 3、replace 當日歷已經存在的情況下是否替換,true=替換, false=不替換 如果不替換還出現重復的情況會拋出異常。
 4、updateTriggers 這個參數比較重要,它的意思是當一個已經存在與調度引擎中的觸發器,并且已經引用了一個日歷,比如:一個(觸發器A)關聯了一個日歷,這個日歷過濾每個星期日。
現在過了一段時間這個日歷更新了(星期六也過濾),那么這個屬性是用來指示觸發器是否使用新的日歷。不然的話(觸發器A)仍然使用舊版本的日歷,如果在有新添加到引擎中的觸發器才會使用新日歷。
持久化
簡介
實現持久化有2種方式。
 方式1:自己維護一張表,操作定時任務時同時修改這張表(推薦)。?
 方式2:使用官方的建表語句(不推薦,因為它要創建11張表,這太多了)。
自己維護表
?表大概這樣
drop table if exists t_quartz;create table t_quartz (id bigint(20) not null auto_increment comment '主鍵id',task_name varchar(32) comment '任務名',cron_expression varchar(32) comment 'cron表達式',param varchar(32) comment '參數',descript varchar(11) comment '描述',quartz_status tinyint(255) comment '啟動狀態(0--啟動1--停止)',status tinyint(1) default 0 comment '狀態(0--正常1--停用)',del_flag tinyint(1) default 0 comment '刪除狀態(0,正常,1已刪除)',create_time datetime comment '創建時間',create_user_id bigint(20) comment '創建人的id',primary key (id) )type = InnoDB;alter table t_quartz comment '定時任務信息表';官方表
官方網址:Quartz建表的sql
對于mysql的建表語句:
-- In your Quartz properties file, you'll need to set -- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate -- By: Ron Cordell - roncordell -- I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM. DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; DROP TABLE IF EXISTS QRTZ_LOCKS; DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; DROP TABLE IF EXISTS QRTZ_TRIGGERS; DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; DROP TABLE IF EXISTS QRTZ_CALENDARS;CREATE TABLE QRTZ_JOB_DETAILS( SCHED_NAME VARCHAR(120) NOT NULL, JOB_NAME VARCHAR(190) NOT NULL, JOB_GROUP VARCHAR(190) NOT NULL, DESCRIPTION VARCHAR(250) 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 NULL, PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_TRIGGERS ( SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_NAME VARCHAR(190) NOT NULL, TRIGGER_GROUP VARCHAR(190) NOT NULL, JOB_NAME VARCHAR(190) NOT NULL, JOB_GROUP VARCHAR(190) NOT NULL, DESCRIPTION VARCHAR(250) NULL, NEXT_FIRE_TIME BIGINT(13) NULL, PREV_FIRE_TIME BIGINT(13) NULL, PRIORITY INTEGER NULL, TRIGGER_STATE VARCHAR(16) NOT NULL, TRIGGER_TYPE VARCHAR(8) NOT NULL, START_TIME BIGINT(13) NOT NULL, END_TIME BIGINT(13) NULL, CALENDAR_NAME VARCHAR(190) NULL, MISFIRE_INSTR SMALLINT(2) NULL, JOB_DATA BLOB NULL, PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_NAME VARCHAR(190) NOT NULL, TRIGGER_GROUP VARCHAR(190) 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), FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_CRON_TRIGGERS ( SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_NAME VARCHAR(190) NOT NULL, TRIGGER_GROUP VARCHAR(190) NOT NULL, CRON_EXPRESSION VARCHAR(120) NOT NULL, TIME_ZONE_ID VARCHAR(80), PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_SIMPROP_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(190) NOT NULL,TRIGGER_GROUP VARCHAR(190) NOT NULL,STR_PROP_1 VARCHAR(512) NULL,STR_PROP_2 VARCHAR(512) NULL,STR_PROP_3 VARCHAR(512) NULL,INT_PROP_1 INT NULL,INT_PROP_2 INT NULL,LONG_PROP_1 BIGINT NULL,LONG_PROP_2 BIGINT NULL,DEC_PROP_1 NUMERIC(13,4) NULL,DEC_PROP_2 NUMERIC(13,4) NULL,BOOL_PROP_1 VARCHAR(1) NULL,BOOL_PROP_2 VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_BLOB_TRIGGERS ( SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_NAME VARCHAR(190) NOT NULL, TRIGGER_GROUP VARCHAR(190) NOT NULL, BLOB_DATA BLOB NULL, PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP), FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_CALENDARS ( SCHED_NAME VARCHAR(120) NOT NULL, CALENDAR_NAME VARCHAR(190) NOT NULL, CALENDAR BLOB NOT NULL, PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)) ENGINE=InnoDB;CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( SCHED_NAME VARCHAR(120) NOT NULL, TRIGGER_GROUP VARCHAR(190) NOT NULL, PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)) ENGINE=InnoDB;CREATE TABLE QRTZ_FIRED_TRIGGERS ( SCHED_NAME VARCHAR(120) NOT NULL, ENTRY_ID VARCHAR(95) NOT NULL, TRIGGER_NAME VARCHAR(190) NOT NULL, TRIGGER_GROUP VARCHAR(190) NOT NULL, INSTANCE_NAME VARCHAR(190) NOT NULL, FIRED_TIME BIGINT(13) NOT NULL, SCHED_TIME BIGINT(13) NOT NULL, PRIORITY INTEGER NOT NULL, STATE VARCHAR(16) NOT NULL, JOB_NAME VARCHAR(190) NULL, JOB_GROUP VARCHAR(190) NULL, IS_NONCONCURRENT VARCHAR(1) NULL, REQUESTS_RECOVERY VARCHAR(1) NULL, PRIMARY KEY (SCHED_NAME,ENTRY_ID)) ENGINE=InnoDB;CREATE TABLE QRTZ_SCHEDULER_STATE ( SCHED_NAME VARCHAR(120) NOT NULL, INSTANCE_NAME VARCHAR(190) NOT NULL, LAST_CHECKIN_TIME BIGINT(13) NOT NULL, CHECKIN_INTERVAL BIGINT(13) NOT NULL, PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)) ENGINE=InnoDB;CREATE TABLE QRTZ_LOCKS ( SCHED_NAME VARCHAR(120) NOT NULL, LOCK_NAME VARCHAR(40) NOT NULL, PRIMARY KEY (SCHED_NAME,LOCK_NAME)) ENGINE=InnoDB;CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY); CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME); CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME); CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME); CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);commit;修改application.yml
spring:quartz:# 將任務等保存化到數據庫job-store-type: jdbc #默認是memoryproperties:org:quartz:jobStore:driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate其他詳細配置
spring:quartz:# 程序結束時會等待quartz相關的內容結束wait-for-jobs-to-complete-on-shutdown: true# QuartzScheduler啟動時更新己存在的Job,這樣就不用每次修改targetObject后刪除qrtz_job_details表對應記錄overwrite-existing-jobs: truejdbc:# 每次啟動重新創建數據庫中Quartz相關的表。若自己事先創建,可不配置下邊兩項initialize-schema: alwaysschema: classpath:schema/tables_mysql.sqlquartz.properties
org.quartz.scheduler.instanceName = MyScheduler org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export = false org.quartz.scheduler.rmi.proxy = false org.quartz.scheduler.wrapJobExecutionInUserTransaction = false# 線程池配置 org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true# 持久化配置 org.quartz.jobStore.misfireThreshold = 50000 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX# 支持集群 org.quartz.jobStore.isClustered = true org.quartz.jobStore.useProperties:true org.quartz.jobStore.clusterCheckinInterval = 15000org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.dataSource = qzDS#數據源連接信息,quartz默認使用c3p0數據源可以被自定義數據源覆蓋 org.quartz.dataSource.qzDS.driver = org.quartz.dataSource.qzDS.URL = org.quartz.dataSource.qzDS.user = root org.quartz.dataSource.qzDS.password = 123456 org.quartz.dataSource.qzDS.maxConnections = 10注意:quartz.properties里邊的配置,都可以放到application.yml里的spring.?quartz.properties下邊:
spring:quartz:properties:org:quartz:..原因:在QuartzAutoConfiguration類內,會自動調用SchedulerFactoryBean的setQuartzProperties方法,把spring.quartz.properties內的所有配置進行設置:
@Bean @ConditionalOnMissingBean public SchedulerFactoryBean quartzScheduler() {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(this.applicationContext.getAutowireCapableBeanFactory()));// 如果配置了spring.quartz.propertiesif (!this.properties.getProperties().isEmpty()) {// 將所有properties設置到QuartzPropertiesschedulerFactoryBean.setQuartzProperties(this.asProperties(this.properties.getProperties()));} ......省略部分代碼總結
以上是生活随笔為你收集整理的SpringBoot整合Quartz--使用/教程/实例的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Byte历险记(tomcat+web游历
- 下一篇: 论文阅读:基于多模态词向量的语句距离计算
