SpringBoot系列:Spring Boot集成定時任務Quartz

来源:https://www.cnblogs.com/imyanger/archive/2019/11/09/11828301.html
-Advertisement-
Play Games

一、關於Quartz Quartz是OpenSymphony開源組織在Job scheduling領域又一個開源項目,它可以與J2EE與J2SE應用程式相結合也可以單獨使用。在java企業級應用中,Quartz是使用最廣泛的定時調度框架。 在Quartz中的主要概念: Scheduler:調度任務的 ...


一、關於Quartz

Quartz是OpenSymphony開源組織在Job scheduling領域又一個開源項目,它可以與J2EE與J2SE應用程式相結合也可以單獨使用。在java企業級應用中,Quartz是使用最廣泛的定時調度框架。

在Quartz中的主要概念:

  • Scheduler:調度任務的主要API
  • ScheduleBuilder:用於構建Scheduler,例如其簡單實現類SimpleScheduleBuilder
  • Job:調度任務執行的介面,也即定時任務執行的方法
  • JobDetail:定時任務作業的實例
  • JobBuilder:關聯具體的Job,用於構建JobDetail
  • Trigger:定義調度執行計劃的組件,即定時執行
  • TriggerBuilder:構建Trigger

一、Quartz演示示例

在SpringBoot中,我們需要引入quartz的依賴。

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

<!--quartz定時調度依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

首先定義定時具體執行邏輯Job,創建類QuartzJob1,這裡集繼承QuartzJobBean實現executeInternal即可,該方法即定時執行任務邏輯,這裡簡單列印了下當前時間。

public class QuartzJob1 extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("QuartzJob1----" + sdf.format(new Date()));
    }

}

然後創建QuartzConfig,接著定義JobDetail,JobDetail由JobBuilder構建,同時關聯了任務QuartzJob1。

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail jobDetail1(){
        return JobBuilder.newJob(QuartzJob1.class).storeDurably().build();
    }
    
}

最後我們需要定義定時調度Trigger,簡單實現類SimpleScheduleBuilder用於構建Scheduler,TriggerBuilder則用於構建Trigger,

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail jobDetail1(){
        return JobBuilder.newJob(QuartzJob1.class).storeDurably().build();
    }

    @Bean
    public Trigger trigger1(){
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(1) //每一秒執行一次
                .repeatForever(); //永久重覆,一直執行下去
        return TriggerBuilder.newTrigger()
                .forJob(jobDetail1())
                .withSchedule(scheduleBuilder)
                .build();
    }
    
}

這樣一個Quartz定時任務就配置完成了。

其實Job的定義也可以使用內部類,這樣可以省去Job類的創建,例如下麵定時任務2 jobDetail2和trigger2。

@Bean
public JobDetail jobDetail2(){
    QuartzJobBean quartzJob2 = new QuartzJobBean() {
        @Override
        protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("內部類quartzJob2----" + sdf.format(new Date()));
        }
    };
    return JobBuilder.newJob(quartzJob2.getClass()).storeDurably().build();
}

@Bean
public Trigger trigger2(){
    //JobDetail的bean註入不能省略
    //JobDetail jobDetail3 = JobBuilder.newJob(QuartzJob2.class).storeDurably().build();
    SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInSeconds(2) //每2秒執行一次
            .repeatForever(); //永久重覆,一直執行下去
    return TriggerBuilder.newTrigger()
            .forJob(jobDetail2())
            .withSchedule(scheduleBuilder).build();
}

啟動程式,我們就可以看到控制台的時間輸出了。

同時Quartz是支持數據持久化的,可以將定時調度信息持久化到資料庫。

選擇持久化到資料庫,我們需要創建對應的表,建表語句可以在Quartz官網進行下載,解壓後在docs\dbTables目錄下尋找對應資料庫的SQL腳本。

為了方便,我也將該文件放在了項目源碼resources里。

操作資料庫,我們引入相關的依賴。若有ORM框架,例如mybatis,hibernate或者jpa,則無需再引入jdbc依賴。

<!--mysql連接-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<!--druid連接池-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>

<!--jdbc依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

在application.yml配置文件中,我們對quartz持久化方式進行聲明。

server:
  port: 10900

spring:
  profiles:
    active: dev
  quartz:
    job-store-type: jdbc #持久化到資料庫
    properties:
      org:
        quartz:
          datasource:
            # 新版驅動從com.mysql.jdbc.Driver變更為com.mysql.cj.jdbc.Driver
            driver-class-name: com.mysql.cj.jdbc.Driver
            # 數據源需要添加時間標準和指定編碼格式解決亂碼 You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
            url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
            username: root
            password: 1234
          scheduler:
            instancName: clusteredScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate說明支持集群
            tablePrefix: QRTZ_
            isClustered: true
            clusterCheckinInterval: 1000
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 20
            threadPriority: 5

這裡主要就是job-store-type: jdbc,表示持久化到資料庫,然後就是數據源,由於該演示項目沒有其他ORM的數據源,所以這裡將數據源信息定義在了quartz節點下的datasource節點,如果已經存在,可使用同一個屬性配置,當然最關鍵的是QuartzDataSource聲明。

這裡關鍵的是@QuartzDataSource,這個要和項目中已經存在的數據源區分開。

//Error:EmbeddedDatabaseType class not found,Druid數據源初始化需要引入spring-jdbc依賴,JPA或mybatis依賴已經包含該依賴
@Bean
@QuartzDataSource
@ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
DataSource quartzDataSource(){
    return DruidDataSourceBuilder.create().build();
}

這樣持久化就已經配置好了,我們執行sql,再啟動項目,啟動完成後,我們可以看到資料庫中已經有我們的定時調度數據了。

源碼地址:https://github.com/imyanger/springboot-project/tree/master/p25-springboot-quartz


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由 楊柳依 創建於2019年11月3日,最近更新於2019年11月8日 參考資料: "大話設計模式" | "圖解設計模式" | "菜鳥教程—設計模式" UML類圖 【矩形框】代表一個類(Class)。類圖分三層: 第一層顯示類的名稱,如果是抽象類,則就用斜體顯示; 第二層是類的特性,通常就是欄位和屬 ...
  • 雖然之前已經學了2個月python,但仍然感覺學的很亂,沒有系統性;或者說自學的沒有條例,只是追求進度,沒有保證知識點的全面與準確。 從今天開始,從python的基礎變數開始重新整理知識點,梳理忽略的內容。願所學即所會,所會即能用。 1、變數名遵循的規則 只能包含字母、數字和下劃線。需要以字母或下劃 ...
  • 一、概述二、Struts2 快速入門程式2.1 開發流程比較2.2 引入依賴2.2 創建jsp頁面2.3 在web.xml中配置前端控制器2.4 創建struts.xml配置文件2.4 創建一個HelloAction類2.5 在struts.xml文件中配置HelloAction2.6 在index... ...
  • 手寫SpringMVC框架 細嗅薔薇 心有猛虎 背景:Spring 想必大家都聽說過,可能現在更多流行的是Spring Boot 和Spring Cloud 框架;但是SpringMVC 作為一款實現了MVC 設計模式的web (表現層) 層框架,其高開發效率和高性能也是現在很多公司仍在採用的框架; ...
  • 概述 今天給大家分享,在 API 端使用 Gin 框架時,項目的目錄。目錄 ├─ Project Name │ ├─ config //配置文件 │ ├── ... │ ├─ controller //控制器層 │ ├── ... │ ├─ service //業務層 │ ├── ... │ ├─ ...
  • 一、re舉例 import re #查找數字 p = re.compile(r"\d+") #在字元串“ongahjeuf125”中及逆行查找,按照規則p指定的正則進行查找 m = p.match("ong125fdsgdsf48515",3,20)#後面的參數序號3到6的搜索範圍 print(m) ...
  • 1. 引入工程依賴包 2. 編寫DAO介面 3. 編寫SQL配置文件(本人不太習慣註解,習慣將SQL寫在配置文件中) 4. 配置myBatis配置類,也可以放在啟動類上 5. 配置application.yml文件 6. 編寫controller,調用MyBatis 源代碼: "https://gi ...
  • 概述首先同步下項目概況:上篇文章分享了,使用 go modules 初始化項目,這篇文章咱們分享: 規劃目錄結構 模型綁定和驗證 自定義驗證器 制定 API 返回結構廢話不多說,咱們開始吧。規劃目錄結構 ├─ go-gin-api │ ├─ app │ ├─ config //配置文件 │ ├─ c ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...