1. 程式人生 > >一起來學SpringBoot(十一)定時任務的使用

一起來學SpringBoot(十一)定時任務的使用

Quartz是一個功能豐富的開源作業排程庫,幾乎可以整合在任何Java應用程式中 - 從最小的獨立應用程式到最大的電子商務系統。Quartz可用於建立簡單或複雜的計劃,以執行數十,數百甚至數萬個作業; 將任務定義為標準Java元件的作業,這些元件可以執行幾乎任何可以程式設計的程式。Quartz Scheduler包含許多企業級功能,例如支援JTA事務和叢集。springboot在2.x後加入了quartz的支援,可以說真的是這個start還是做的不錯的!!

spring定時器

首先呢說一下spring自帶的定時器

package com.maoxs.conf;

import org.springframework.
beans.factory.annotation.Configurable; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @Component @Configurable @EnableScheduling
public class ScheduledTasks { @Scheduled(fixedRate = 1000 * 30) public void reportCurrentTime() { System.out.println("任務執行 " + dateFormat().format(new Date())); } //每1分鐘執行一次 @Scheduled(cron = "0 */1 * * * * ") public void reportCurrentByCron() { System.out.println
("任務執行" + dateFormat().format(new Date())); } private SimpleDateFormat dateFormat() { return new SimpleDateFormat("HH:mm:ss"); } }

其中呢  @EnableScheduling:標註啟動定時任務 @Scheduled(fixedRate = 1000 * 30) 定義某個定時任務。當然也可以使用cron表示式。但是呢需要進行任務的持久和複雜的管控,肯定就不行了,下面上quartz。

quartz

首先呢要使用首先加入依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

然後在yml中加入

spring:
    quartz:
      properties:
        org:
          quartz:
            scheduler:
              instanceName: MyScheduler
              instanceId: AUTO  #如果使用叢集,instanceId必須唯一,設定成AUTO
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true
      job-store-type: memory #jdbc 為持久化,memory 為記憶體

這裡呢我封裝了一個操作的類

package com.maoxs.conf;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;

/**
 * quartz管理類
 *
 * @author fulin
 */
@Service
public class QuartzManager {
    @Autowired
    private Scheduler  scheduler;

    /**
     * 增加一個job
     *
     * @param jobClass     任務實現類
     * @param jobName      任務名稱
     * @param jobGroupName 任務組名
     * @param jobCron      cron表示式(如:0/5 * * * * ? )
     */
    public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, String jobCron) {
        try {
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                    .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobCron)).startNow().build();
            scheduler.scheduleJob(jobDetail, trigger);
            if (!scheduler.isShutdown()) {
                scheduler.start();
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }


    /**
     * 建立or更新任務,存在則更新不存在建立
     *
     * @param jobClass     任務類
     * @param jobName      任務名稱
     * @param jobGroupName 任務組名稱
     * @param jobCron      cron表示式
     */
    public void addOrUpdateJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, String jobCron) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                addJob(jobClass, jobName, jobGroupName, jobCron);
            } else {
                if (trigger.getCronExpression().equals(jobCron)) {
                    return;
                }
                updateJob(jobName, jobGroupName, jobCron);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param jobClass
     * @param jobName
     * @param jobGroupName
     * @param jobTime
     */
    public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, int jobTime) {
        addJob(jobClass, jobName, jobGroupName, jobTime, -1);
    }

    public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, int jobTime, int jobTimes) {
        try {
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任務名稱和組構成任務key
                    .build();
            // 使用simpleTrigger規則
            Trigger trigger = null;
            if (jobTimes < 0) {
                trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                        .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
                        .startNow().build();
            } else {
                trigger = TriggerBuilder
                        .newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
                                .repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
                        .startNow().build();
            }
            scheduler.scheduleJob(jobDetail, trigger);
            if (!scheduler.isShutdown()) {
                scheduler.start();
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    public void updateJob(String jobName, String jobGroupName, String jobTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
            // 重啟觸發器
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 刪除任務一個job
     *
     * @param jobName      任務名稱
     * @param jobGroupName 任務組名
     */
    public void deleteJob(String jobName, String jobGroupName) {
        try {
            scheduler.deleteJob(new JobKey(jobName, jobGroupName));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 暫停一個job
     *
     * @param jobName
     * @param jobGroupName
     */
    public void pauseJob(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 恢復一個job
     *
     * @param jobName
     * @param jobGroupName
     */
    public void resumeJob(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }


    /**
     * 立即執行一個job
     *
     * @param jobName
     * @param jobGroupName
     */
    public void runAJobNow(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }


    /**
     * 獲取所有計劃中的任務列表
     *
     * @return
     */
    public List<Map<String, Object>> queryAllJob() {
        List<Map<String, Object>> jobList = null;
        try {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            jobList = new ArrayList<Map<String, Object>>();
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("jobName", jobKey.getName());
                    map.put("jobGroupName", jobKey.getGroup());
                    map.put("description", "觸發器:" + trigger.getKey());
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    map.put("jobStatus", triggerState.name());
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        map.put("jobTime", cronExpression);
                    }
                    jobList.add(map);
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }


    /**
     * 獲取所有正在執行的job
     *
     * @return
     */
    public List<Map<String, Object>> queryRunJon() {
        List<Map<String, Object>> jobList = null;
        try {
            List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
            jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
            for (JobExecutionContext executingJob : executingJobs) {
                Map<String, Object> map = new HashMap<String, Object>();
                JobDetail jobDetail = executingJob.getJobDetail();
                JobKey jobKey = jobDetail.getKey();
                Trigger trigger = executingJob.getTrigger();
                map.put("jobName", jobKey.getName());
                map.put("jobGroupName", jobKey.getGroup());
                map.put("description", "觸發器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                map.put("jobStatus", triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    map.put("jobTime", cronExpression);
                }
                jobList.add(map);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }

}

然後呢新建一個任務類,任務類一定要繼承QuartzJobBean,其實跟之前一樣,QuartzJobBean也是實現的job類。

package com.maoxs.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class OrderTimeoutJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("武器強化失敗");
    }
}

建立一個測試類玩玩

package com.maoxs;

import com.maoxs.conf.QuartzManager;
import com.maoxs.dao.QuartzMapper;
import com.maoxs.job.OrderTimeoutJob;
import com.maoxs.pojo.QuartzEntity;
import com.maoxs.service.JobService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Collections;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringbootQuartzApplicationTests {
    @Autowired
    private QuartzManager quartzManager;
    @Test
    public void mcreateTask() throws InterruptedException {
        quartzManager.addJob(OrderTimeoutJob.class, "maoxs", "q1", "0/1 * * * * ?");
        log.info("新增任務成功");
        Thread.sleep(10000);
        quartzManager.pauseJob("maoxs", "q1");
        log.info("暫停任務成功");
        Thread.sleep
            
           

相關推薦

起來SpringBoot定時任務的使用

Quartz是一個功能豐富的開源作業排程庫,幾乎可以整合在任何Java應用程式中 - 從最小的獨立應用程式到最大的電子商務系統。Quartz可用於建立簡單或複雜的計劃,以執行數十,數百甚至數萬個作業; 將任務定義為標準Java元件的作業,這些元件可以執行幾乎任何

起來SpringBoot優雅的整合Shiro

Apache Shiro是一個功能強大且易於使用的Java安全框架,可執行身份驗證,授權,加密和會話管理。藉助Shiro易於理解的API,您可以快速輕鬆地保護任何應用程式 - 從最小的移動應用程式到最大的Web和企業應用程式。網上找到大部分文章都是以前Sprin

起來SpringBootMybatisPlus的整合

MyBatis-Plus(簡稱 MP)是一個MyBatis的增強工具 ,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。本篇文章介紹的是與springboot的整合。 特性 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,

起來SpringBoot快取的使用

Spring Framework支援透明地嚮應用程式新增快取。從本質上講,抽象將快取應用於方法,從而根據快取中可用的資訊減少執行次數。快取邏輯應用透明,不會對呼叫者造成任何干擾。只要通過@EnableCaching 註釋啟用了快取支援,Spring Boot就會

起來SpringBoot | 第篇:整合Swagger線上除錯

SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 隨著網際網路技

起來SpringBoot | 第二六篇:輕鬆搞定安全框架Shiro

SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 Shiro 是

起來SpringBoot | 第九篇:輕鬆搞定資料驗證

SpringBoot是為了簡化Spring應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 對於任何一個

起來SpringBoot | 第四篇:強大的 actuator 服務監控與管理

SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 actuato

起來SpringBoot | 第五篇:actuator與spring-boot-admin 可以說的祕密

SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 一起來學Spr

跟我springbootspringboot-web-webjars和靜態資源對映規則

一.簡介 在使用springboot的web應用時,首先需要建立springboot應用,選擇我們自己需要的模組,springboot已經預設將這些場景配置好了,只需要在配置檔案指定少量的配置就可以執行起來。在使用之前我們需要了解自動配置的原理,可以參考跟我學s

Nodejs學習筆記定時任務node-schedule)

sch 接下來 bsp 消息 分享 學習筆記 day 筆記 定時器 寫在之前   在實際開發項目中,會遇到很多定時任務的工作。比如:定時導出某些數據、定時發送消息或郵件給用戶、定時備份什麽類型的文件等等   一般可以寫個定時器,來完成相應的需求,在node.js中自已實現也

Nodejs學習筆記--- 定時任務node-schedule)

目錄 寫在之前   在實際開發專案中,會遇到很多定時任務的工作。比如:定時匯出某些資料、定時傳送訊息或郵件給使用者、定時備份什麼型別的檔案等等   一般可以寫個定時器,來完成相應的需求,在node.js中自已實現也非常容易,接下來要介紹的是node-schedule來完成定時任務   下面就用

起來SpringBoot | 第二十三篇:輕鬆搞定重複提交分散式鎖

SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 在 一起來學S

SpringBoot-- 動態數據源

eterm 屬性 this runt ids 指定 之前 exception factory SpringBoot中使用動態數據源可以實現分布式中的分庫技術,比如查詢用戶 就在用戶庫中查詢,查詢訂單 就在訂單庫中查詢。 一、配置文件application.properti

起來redis

硬盤 目前 入門指南 開發 方式 大內存 rem 生存 設置 redis是一個開源的,高性能的,基於鍵值對的緩存與存儲系統通過提供多種鍵值數據類型來適應不同場景下的緩存與存儲需求。 同時redis的諸多高層級功能使其可以勝任消息隊列,任務隊列等不同的角色。 特性 Red

SpringBootSpringBoot整合Kafka

一、準備工作 提前說明:如果你執行出問題,請檢查Kafka的版本與SpringBoot的版本是否與我文中的一致,本文中的環境已經經過測試。 Kafka服務版本為 kafka_2.11-1.1.0 (Scala), 也就是1.1.0 SpringBoot版本:1.5.10.R

大學生程式設計:如何建立程式設計邏輯思維

編者按:誰沒有年輕過,誰沒有二過? 作為一個軟體工程的學生,雖然專業課(C,資料結構之類的)學得算是過得去吧,但是始終覺得沒有建立起程式設計所需要的邏輯思維。也許跟我從小數學不好有關。打個比方吧,簡單的問題可以很快搞定,但是遇到較為複雜的問題,就很難將其抽象出來,總感覺腦中一團混沌。為此

springboot 整合攔截器和過濾器及監聽器

一、實現過濾器Filter 1.新建類(注意這個類上的註解@Component,這個註解不可以用,如果不用,就得在springboot的那個標有@SpringBootApplication的類上加上@ServletComponentScan,總之是讓spring掃描並管理這

草根Python列舉類

前言 雖然沒多少閱讀,可是還是堅持寫下去。對 Python 感興趣的童鞋可以加入 Python 學習討論微信群喔。可以先加我微信,然後拉進群。本人微信: 目錄 一、列舉類的使用 實際開發中,我們離不開定義常量,當我們需要定義常量時,其中一

零基礎FPGA腳印之基於FIFO的串列埠傳送機設計全流程及常見錯誤詳解

     今天要寫的是一段基於FIFO的串列埠傳送機設計,之前也寫過串列埠傳送的電路,這次寫的與上次的有幾分類似。這段程式碼也是我看過別人寫過的之後,消化一下再根據自己的理解寫出來的,下面是我寫這段程式碼的全部流程和思路,希望對剛開始接觸的朋友來說有一點點的幫助,也希望有