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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Springboot2 Quartz实现JAVA定时任务的动态配置

發布時間:2024/9/27 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Springboot2 Quartz实现JAVA定时任务的动态配置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

動態配置Quartz。沒接觸過定時任務的同學可以先看下此篇:JAVA定時任務實現的幾種方式

文章目錄

          • 一、需求背景
            • 1. 問題現象
            • 2. 問題分析
            • 3. 解決方案
          • 二、需求背景
            • 2.1. maven依賴
            • 2.2. 創建一個任務表
            • 2.3. 實現步驟
          • 三、代碼邏輯
            • 3.1. Quartz配置
            • 3.2. 啟動項目,加載監聽
            • 3.3. 讀取數據庫,加載scheduler調度器
            • 3.4. 添加任務到Quartz調度器
            • 3.5. 根據任務調度運行job類
            • 3.6. 實例化job類,注入要運行的service
          • 四、常見的Quartz的API
            • 4.1. 新增一個job
            • 4.2. 暫停一個job
            • 4.2. 刪除一個job
            • 4.3. 暫停一個job
            • 4.4. 立即執行一個job
            • 4.5. 更新job表達式
          • 五、源碼下載和運行
            • 5.1. 源碼地址
            • 5.2. 源碼下載
            • 5.3. 項目運行

一、需求背景
1. 問題現象

定時任務實現方式: 1.JDK 的Timer類 2.Quartz 3.SpringTask 。
生產上三種方式我都有使用過。但是使用過程中用的最多的便是xml配置的方式,這種方式最簡單,無代碼侵入,也比較好理解。但是卻有個致命的缺點,比如你要改某個任務的觸發時間,亦或是你要新增一個任務,暫停一個任務。怎么做?
停應用!改XML配置!重新啟動!
怎樣解決上述致命的問題現象呢?

2. 問題分析

請大家想一想:停應用、修改XML配置!重新啟動是為了什么?
應該是首先修改Quartz的配置文件,然后,修改一些屬性配置參數,最后重新啟動項目加載配置文件,對吧!
哪怎樣可以動態配置Quartz的配置文件的呢?

3. 解決方案

哪怎樣動態配置Quartz的屬性參數的呢?如果把Quartz需要的重點關鍵參數存到數據庫,通過頁面就可以修改Quartz的屬性參數了,對吧!
那問題又來了,屬性參數修改了,那有怎樣讓屬性參數生效呢?
其實Quartz官方提供了一些日常操作的API接口方法,只需要咱們把需要的參數傳遞給對應的api接口即可,因此,咱們的思路,應該這樣想,操作增增加定時任務就找Quartz的增加api,傳參數,其他的一樣,對吧!

既然思路有了,那咱們就應該提前去做以下幾件事:
1.Quartz常見的api在哪?或者說在哪里可以找到
2.找出常見的Quartz的api
3.認真分析常見的Quartz的api需要怎樣才能觸發

溫馨建議:
自己寫一個demo或者main方法單元測試一下,效果最好,不斷完善

舉個例子:
增加定時任務,一般需要幾個或者什么參數,提前弄明白
這樣就可以動態不停應用通過Quartz實現了不停機添加、暫停、刪除、立即觸發任務的方法

二、需求背景
2.1. maven依賴
<!-- quartz --> <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId> </dependency>
2.2. 創建一個任務表
CREATE TABLE `sys_task` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`job_name` varchar(255) DEFAULT NULL COMMENT '任務名',`description` varchar(255) DEFAULT NULL COMMENT '任務描述',`cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表達式',`bean_class` varchar(255) DEFAULT NULL COMMENT '任務執行時調用哪個類的方法 包名+類名',`job_status` varchar(255) DEFAULT NULL COMMENT '任務狀態',`job_group` varchar(255) DEFAULT NULL COMMENT '任務分組',`create_user` varchar(64) DEFAULT NULL COMMENT '創建者',`create_time` datetime DEFAULT NULL COMMENT '創建時間',`update_user` varchar(64) DEFAULT NULL COMMENT '更新者',`update_time` datetime DEFAULT NULL COMMENT '更新時間',PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;
2.3. 實現步驟

①啟動項目,啟動task監聽
②讀取數據庫,將開啟的任務job和trigger加載到scheduler調度器
③根據任務調度運行job類
④每次運行利用AdaptableJobFactory實例化job類,以便注入要運行的service
聽著是不是很簡單,但卻還是一頭霧水,且聽我慢慢道來~~

三、代碼邏輯
3.1. Quartz配置

Springboot的配置方法,常規Spring項目可以在xml中配置

@Configuration public class QuartzConfigration {@Autowiredprivate JobFactory jobFactory;@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();try {schedulerFactoryBean.setOverwriteExistingJobs(true);schedulerFactoryBean.setQuartzProperties(quartzProperties());schedulerFactoryBean.setJobFactory(jobFactory);} catch (Exception e) {e.printStackTrace();}return schedulerFactoryBean;}// 指定quartz.properties,可在配置文件中配置相關屬性@Beanpublic Properties quartzProperties() throws IOException {PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));propertiesFactoryBean.afterPropertiesSet();return propertiesFactoryBean.getObject();}// 創建schedule@Bean(name = "scheduler")public Scheduler scheduler() {return schedulerFactoryBean().getScheduler();} }
3.2. 啟動項目,加載監聽
@Component @Order(value = 1) public class ScheduleJobInitListener implements CommandLineRunner {@AutowiredTaskService scheduleJobService;@Overridepublic void run(String... arg0) throws Exception {try {scheduleJobService.initSchedule();} catch (Exception e) {e.printStackTrace();}} }

CommandLineRunner類似Spring框架的ApplicationListener監聽器。官方的解釋是:
Interface used to indicate that a bean should run when it is contained within a SpringApplication. Multiple CommandLineRunner beans can be defined within the same application context and can be ordered using the Ordered interface or Order @Order annotation.
接口被用作將其加入spring容器中時執行其run方法。多個CommandLineRunner可以被同時執行在同一個spring上下文中并且執行順序是以order注解的參數順序一致。

3.3. 讀取數據庫,加載scheduler調度器
@Overridepublic void initSchedule() throws SchedulerException {// 這里獲取任務信息數據List<TaskDO> jobList = taskMapper.list();for (TaskDO task : jobList) {if (JobStatusEnum.RUNNING.getCode().equals(task.getJobStatus())) {quartzManager.addJob(task);}}}
3.4. 添加任務到Quartz調度器
/*** 添加任務*/ @SuppressWarnings("unchecked")public void addJob(TaskDO task) {try {// 創建jobDetail實例,綁定Job實現類// 指明job的名稱,所在組的名稱,以及綁定job類Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance().getClass());JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup())// 任務名稱和組構成任務key.build();// 定義調度觸發規則// 使用cornTrigger規則Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 觸發器key.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND)).withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build();// 把作業和觸發器注冊到任務調度中scheduler.scheduleJob(jobDetail, trigger);// 啟動if (!scheduler.isShutdown()) {scheduler.start();}} catch (Exception e) {e.printStackTrace();}}

Scheduler作為Quartz的核心調度器,有將近50多個API接口,包括任務的添加,暫停,恢復,刪除等一系列的API,這里僅介紹一些常用的,想要了解更多可以稍后看下彩蛋部分。

1、start()方法:只有調用start()方法后,Scheduler線程才開始啟動觸發器trigger,運行job
2、pauseJob(JobKey jobKey) :根據指定的JobDetail key暫停job。
3、resumeJob(JobKey jobKey) :根據指定的key恢復一個job。
4、deleteJob(JobKey jobKey) :刪除一個job
5、triggerJob(JobKey jobKey) :觸發一個JobDetail(現在執行)。
6、rescheduleJob(TriggerKey triggerKey, Trigger newTrigger):

用給定的鍵刪除觸發器,并存儲新的觸發器,它必須與同一個作業相關聯(新觸發器必須具有指定的作業名和組)-然而,新觸發器不必具有與舊觸發器相同的名稱。

3.5. 根據任務調度運行job類

其實這一步是不需要我們編寫的,在我們將正確的JobDetail 和 Trigger 表達式加載到任務調度后,調度器會自動觸發任務的執行

3.6. 實例化job類,注入要運行的service

工廠類

@Component public class JobFactory extends AdaptableJobFactory {//這個對象Spring會幫我們自動注入進來,也屬于Spring技術范疇.//為什么需要這個類呢,在我寫的這個demo中,大家可以將此類刪掉,發現程序也可以正確運行,可是我為什么還是加上呢。//大家可以看下我們的任務類,大家可以看到Job對象的實例化過程是在Quartz中進行的,這時候我們將spring的東西注入進來,肯定是行不通的,所以需要這個類@Autowiredprivate AutowireCapableBeanFactory capableBeanFactory;@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {//調用父類的方法Object jobInstance = super.createJobInstance(bundle);//進行注入capableBeanFactory.autowireBean(jobInstance);return jobInstance;} }

任務類

@DisallowConcurrentExecution //作業不并發 @Component public class HelloWorldJob implements Job{@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {System.out.println("歡迎使用yyblog,這是一個定時任務 --小賣鋪的老爺爺!"+ DateUtils.fullTime(new Date())); } }

好了,大功告成,一個簡單的動態配置的定時任務已經完成。是不是so easy!
下面我們再來簡單實現下其他的幾種常用的api吧。

四、常見的Quartz的API
4.1. 新增一個job
/*** 添加任務* * @param scheduleJob* @throws SchedulerException*/ @SuppressWarnings("unchecked")public void addJob(TaskDO task) {try {// 創建jobDetail實例,綁定Job實現類// 指明job的名稱,所在組的名稱,以及綁定job類Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance().getClass());JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup())// 任務名稱和組構成任務key.build();// 定義調度觸發規則// 使用cornTrigger規則Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 觸發器key.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND)).withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build();// 把作業和觸發器注冊到任務調度中scheduler.scheduleJob(jobDetail, trigger);// 啟動if (!scheduler.isShutdown()) {scheduler.start();}} catch (Exception e) {e.printStackTrace();}}
4.2. 暫停一個job
/*** 暫停一個job* * @param task* @throws SchedulerException*/public void pauseJob(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.pauseJob(jobKey);}
4.2. 刪除一個job
/*** 刪除一個job* * @param task* @throws SchedulerException*/public void deleteJob(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.deleteJob(jobKey);}
4.3. 暫停一個job
在這里插入代碼片
4.4. 立即執行一個job
/*** 立即執行job* * @param task* @throws SchedulerException*/public void runJobNow(TaskDO task) throws SchedulerException {JobKey jobKey = JobKey.jobKey(task.getJobName(), task.getJobGroup());scheduler.triggerJob(jobKey);}
4.5. 更新job表達式
/*** 更新job時間表達式* * @param task* @throws SchedulerException*/public void updateJobCron(TaskDO task) throws SchedulerException {TriggerKey triggerKey = TriggerKey.triggerKey(task.getJobName(), task.getJobGroup());CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();scheduler.rescheduleJob(triggerKey, trigger);}
五、源碼下載和運行
5.1. 源碼地址

https://gitee.com/gb_90/yyblog

5.2. 源碼下載
git clone git@gitee.com:gb_90/yyblog.git
5.3. 項目運行
#1.進入下載的項目目錄 cd yyblog #2.切換分支到1.0 git checkout 1.0 #3.初始化數據庫(sql在lib下面) #4.修改數據庫連接(application.yml) #5.啟動項目 鏈接:http://localhost:8080 賬號:admin 密碼:123456

Quartz文檔地址:https://github.com/allanzhuo/yyblog/tree/master/doc

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Springboot2 Quartz实现JAVA定时任务的动态配置的全部內容,希望文章能夠幫你解決所遇到的問題。

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