欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot整合quartz項(xiàng)目使用案例

 更新時(shí)間:2023年05月13日 10:31:27   作者:小lee學(xué)編程  
quartz是一個(gè)定時(shí)調(diào)度的框架,就目前市場(chǎng)上來說,其實(shí)有比quartz更優(yōu)秀的一些定時(shí)調(diào)度框架,不但性能比quartz好,學(xué)習(xí)成本更低,而且還提供可視化操作定時(shí)任務(wù),這篇文章主要介紹了springboot整合quartz項(xiàng)目使用(含完整代碼),需要的朋友可以參考下

前言:quartz是一個(gè)定時(shí)調(diào)度的框架,就目前市場(chǎng)上來說,其實(shí)有比quartz更優(yōu)秀的一些定時(shí)調(diào)度框架,不但性能比quartz好,學(xué)習(xí)成本更低,而且還提供可視化操作定時(shí)任務(wù)。例如xxl-Job,elastic-Job這兩個(gè)算是目前工作中使用比較多的定時(shí)調(diào)度框架了,適配于分布式的項(xiàng)目,性能也是很優(yōu)秀。這是很多人就很疑惑,既然這樣我們?yōu)槭裁催€要了解學(xué)習(xí)quartz呢?我個(gè)人覺得學(xué)習(xí)quartz有兩方面,首先xxl-Job,elastic-Job這些框架都是基于quartz的基礎(chǔ)上二次開發(fā)的,學(xué)習(xí)quartz更有利于我們加強(qiáng)理解定時(shí)調(diào)度。第二方面就是工作需求,有一些傳統(tǒng)互聯(lián)網(wǎng)公司還是有很多項(xiàng)目是使用quartz來完成定時(shí)任務(wù)的開發(fā)的,不懂quartz的話,老板叫你寫個(gè)定時(shí)任務(wù)都搞不定。

1. quartz的基礎(chǔ)概念

在這里插入圖片描述

有上圖可以看到,一個(gè)job可以給多個(gè)jobDetail封裝,一個(gè)jobDetail可以給trigger來配置規(guī)則,但是一個(gè)trigger只能裝配一個(gè)jobDetail。

scheduler:可以理解為定時(shí)任務(wù)的工作容器或者說是工作場(chǎng)所,所有定時(shí)任務(wù)都是放在里面工作,可以開啟和停止。

trigger:可以理解為是定時(shí)任務(wù)任務(wù)的工作規(guī)則配置,例如說,沒個(gè)幾分鐘調(diào)用一次,或者說指定每天那個(gè)時(shí)間點(diǎn)執(zhí)行。

jobDetail:定時(shí)任務(wù)的信息,例如配置定時(shí)任務(wù)的名字,群組之類的。

job:定時(shí)任務(wù)的真正的業(yè)務(wù)處理邏輯的地方。

2. quartz的簡單使用

這是quartz的api使用,在官網(wǎng)直接提供使用例子,但是在工作中用不到這種方式的

地址:https://www.quartz-scheduler.org/documentation/quartz-2.3.0/quick-start.html

public class QuartzTest {
    public static void main(String[] args) throws Exception{
        try {
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();
            JobDetail job = newJob(HelloJob.class)
                    .withIdentity("job1", "group1")
                    .build();
            Trigger trigger = newTrigger()
                    .withIdentity("trigger1", "group1")
                    .startNow()
                    .withSchedule(simpleSchedule()
                            .withIntervalInSeconds(2)
                            .repeatForever())
                    .build();
            scheduler.scheduleJob(job, trigger);
            TimeUnit.SECONDS.sleep(20);
            scheduler.shutdown();
        } catch (SchedulerException se) {
            se.printStackTrace();
        }
    }
}

3. quartz與springboot的整合使用

在官網(wǎng)中介紹了,只要你引用了quartz的依賴后,springboot會(huì)自適配調(diào)度器。當(dāng)然我們也可以新建bean,修改SchedulerFactoryBean的一些默認(rèn)屬性值。

使用javaBean方式按實(shí)際業(yè)務(wù)需求初始化SchedulerFactoryBean(可以不要,就用默認(rèn)SchedulerFactoryBean

@Configuration
public class QuartzConfiguration {
    // Quartz配置文件路徑
    private static final String QUARTZ_CONFIG = "config/quartz.properties";
    @Value("${task.enabled:true}")
    private boolean enabled;
    @Autowired
    private DataSource dataSource;
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setDataSource(dataSource);
        // 設(shè)置加載的配置文件
        schedulerFactoryBean.setConfigLocation(new ClassPathResource(QUARTZ_CONFIG));
        // 用于quartz集群,QuartzScheduler 啟動(dòng)時(shí)更新己存在的Job
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        schedulerFactoryBean.setStartupDelay(5);// 系統(tǒng)啟動(dòng)后,延遲5s后啟動(dòng)定時(shí)任務(wù),默認(rèn)為0
        // 啟動(dòng)時(shí)更新己存在的Job,這樣就不用每次修改targetObject后刪除qrtz_job_details表對(duì)應(yīng)記錄了
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        // SchedulerFactoryBean在初始化后是否馬上啟動(dòng)Scheduler,默認(rèn)為true。如果設(shè)置為false,需要手工啟動(dòng)Scheduler
        schedulerFactoryBean.setAutoStartup(enabled);
        return schedulerFactoryBean;
    }
}

要使用quartz實(shí)現(xiàn)定時(shí)任務(wù),首先要新建一個(gè)Job,在springboot中,新建的Job類要繼承QuartzJobBean

public class HelloJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context)  {
        StringJoiner joiner = new StringJoiner(" | ")
                .add("---HelloJob---")
                .add(context.getTrigger().getKey().getName())
                .add(DateUtil.formatDate(new Date()));
        System.out.println(joiner);
    }
}

創(chuàng)建jobDetail和Trigger來啟動(dòng)定時(shí)任務(wù),有兩種方式可以實(shí)現(xiàn),本質(zhì)上就是創(chuàng)建jobDetail和Trigger

方式一:為對(duì)應(yīng)的Job創(chuàng)建JobDetail和Trigger,這種方式有兩個(gè)注意的地方,jobDetail一定要設(shè)置為可持久化.storeDurably(),Trigger創(chuàng)建要用.forJob(“helloJob”),要與JobDetail定義的相同。

@Component
public class HelloJobDetailConfig {
    @Bean
    public JobDetail helloJobDetail(){
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                .withIdentity("helloJob")
                .storeDurably()
                .usingJobData("data", "保密信息")
                .build();
        return jobDetail;
    }
    @Bean
    public Trigger helloJobTrigger(){
        Trigger trigger = TriggerBuilder.newTrigger()
                .forJob("helloJob")
                .withSchedule(simpleSchedule()
                        .withIntervalInSeconds(3)
                        .repeatForever())
                .build();
        return trigger;
    }
}

方式二:在注入Bean之前初始化創(chuàng)建JobDetail和Trigger,然后使用Scheduler來調(diào)用,跟原生API調(diào)用差不多。

@Component
public class HelloJobDetailConfig2 {
    @Autowired
    private Scheduler scheduler;
    @PostConstruct
    protected void InitHelloJob() throws Exception {
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                .withIdentity("helloJob")
//                .storeDurably()
                .usingJobData("data", "保密信息")
                .build();
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("helloTrigger")
                .withSchedule(simpleSchedule()
                        .withIntervalInSeconds(3)
                        .repeatForever())
                .build();
        scheduler.scheduleJob(jobDetail,trigger);
    }
}

4. quartz的持久化

在這里插入圖片描述

quartz持久化有兩種存儲(chǔ),一般情況下quartz相關(guān)的表和業(yè)務(wù)表是放在同一個(gè)數(shù)據(jù)庫里的。但是如果考慮性能問題的話,就要配多數(shù)據(jù)源,業(yè)務(wù)表單獨(dú)一個(gè)庫,quartz相關(guān)的表放在一個(gè)庫。

https://docs.spring.io/spring-boot/docs/2.3.12.RELEASE/reference/html/spring-boot-features.html#boot-features-quartz

spring官網(wǎng)說明,默認(rèn)情況下,使用內(nèi)存中的JobStore。但是,如果應(yīng)用程序中有DataSourcebean,并且spring.quartz是可用的,則可以配置基于JDBC的存儲(chǔ)。將相應(yīng)地配置作業(yè)存儲(chǔ)類型屬性。第二個(gè)配置,每次啟動(dòng)先刪除表數(shù)據(jù)再重新創(chuàng)建(在實(shí)際生產(chǎn)中,個(gè)人更傾向于拿dml來手動(dòng)創(chuàng)建表,這個(gè)值設(shè)置為never)。在quartz的jar包里這個(gè)路徑下有不同數(shù)據(jù)庫的dml:org.quartz.impl.jdbcjobstore

spring.quartz.job-store-type=jdbc

spring.quartz.jdbc.initialize-schema=never

另外一種方式:

要讓Quartz使用DataSource而不是應(yīng)用程序的主DataSource,請(qǐng)聲明DataSourcebean,并用@QuartzDataSource注釋其@bean方法。這樣做可以確保SchedulerFactoryBean和模式初始化都使用Quartz特定的DataSource

@Configuration
public class QuartzDataSourceConfig {
    @Bean
    @QuartzDataSource
    public DataSource quartzDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false");
        return dataSource;
    }
}

還有一點(diǎn)需要注意:當(dāng)jobbean已經(jīng)注入spring容器后,下次不用需要再注入,把@Component注釋掉。

5. quartz的misfire策略

**misfire:**到了任務(wù)觸發(fā)時(shí)間點(diǎn),但是任務(wù)沒有被觸發(fā)

原因:- 使用@DisallowConcurrentExecution注解,而且任務(wù)的執(zhí)行時(shí)間>任務(wù)間隔

-線程池滿了,沒有資源執(zhí)行任務(wù)

-機(jī)器宕機(jī)或者認(rèn)為停止,果斷時(shí)間恢復(fù)運(yùn)行。

@DisallowConcurrentExecution:這個(gè)是比較常用的注解,證上一個(gè)任務(wù)執(zhí)行完后,再去執(zhí)行下一個(gè)任務(wù),不會(huì)允許任務(wù)并行執(zhí)行。

@PersistJobDataAfterExecution:任務(wù)執(zhí)行完后,會(huì)持久化保留數(shù)據(jù)到下次 執(zhí)行

針對(duì)不同的ScheduleBuilder,可以設(shè)置不同的失火策略,SimpleScheduleBuilder和非SimpleScheduleBuilder,

SimpleScheduleBuilder有六種,而非SimpleScheduleBuilder有三種,在實(shí)際工作中我們使用的比較的是CronScheduleBuilder.

.withMisfireHandlingInstructionIgnoreMisfires()
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1
所有未觸發(fā)的執(zhí)行都會(huì)立即執(zhí)行,然后觸發(fā)器再按計(jì)劃運(yùn)行。

.withMisfireHandlingInstructionFireAndProceed()
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1
立即執(zhí)行第一個(gè)錯(cuò)誤的執(zhí)行并丟棄其他(即所有錯(cuò)誤的執(zhí)行合并在一起),也就是說無論錯(cuò)過了多少次觸發(fā)器的執(zhí)行,都只會(huì)立即執(zhí)行一次,然后觸發(fā)器再按計(jì)劃運(yùn)行。(默認(rèn)的失火策略)

.withMisfireHandlingInstructionDoNothing()
MISFIRE_INSTRUCTION_DO_NOTHING = 2
所有未觸發(fā)的執(zhí)行都將被丟棄,然后再觸發(fā)器的下一個(gè)調(diào)度周期按計(jì)劃運(yùn)行。

6、總結(jié)

關(guān)于quartz還有一個(gè)很重要的點(diǎn)就是corn表達(dá)式,這個(gè)個(gè)人認(rèn)為沒必要死記硬背,實(shí)在不會(huì)寫的,上網(wǎng)找corn表達(dá)式在線轉(zhuǎn)換就可以了。

一個(gè)簡單demo的代碼地址:https://gitee.com/gorylee/quartz-demo
生產(chǎn)項(xiàng)目中quartz的配置使用代碼地址:https://gitee.com/gorylee/learnDemo/tree/master/quartzDemo

到此這篇關(guān)于springboot整合quartz項(xiàng)目使用(含完整代碼)的文章就介紹到這了,更多相關(guān)springboot整合quartz內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java批量修改文件名的實(shí)例代碼

    Java批量修改文件名的實(shí)例代碼

    幾天前在163公開課上下了一些mp4視頻文件。發(fā)現(xiàn)課程名和文件名不對(duì)應(yīng),想到編個(gè)程序批量修改。先分析網(wǎng)頁源代碼將課程名和文件名一一對(duì)應(yīng),存儲(chǔ)在一個(gè)文件里,然后使用Java讀取該文件進(jìn)而修改文件名。
    2013-04-04
  • jedis的return行為源碼解析

    jedis的return行為源碼解析

    這篇文章主要為大家介紹了jedis的return行為源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Java使用阻塞隊(duì)列控制線程通信的方法實(shí)例詳解

    Java使用阻塞隊(duì)列控制線程通信的方法實(shí)例詳解

    這篇文章主要介紹了Java使用阻塞隊(duì)列控制線程通信的方法,結(jié)合實(shí)例形式詳細(xì)分析了java使用阻塞隊(duì)列控制線程通信的相關(guān)原理、方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Spring Boot Mysql 數(shù)據(jù)庫操作示例

    Spring Boot Mysql 數(shù)據(jù)庫操作示例

    本篇文章主要介紹了Spring Boot Mysql 數(shù)據(jù)庫操作示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • Spring BeanPostProcessor源碼示例解析

    Spring BeanPostProcessor源碼示例解析

    這篇文章主要為大家介紹了Spring BeanPostProcessor源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • SpringBoot實(shí)現(xiàn)自定義線程池的方法

    SpringBoot實(shí)現(xiàn)自定義線程池的方法

    這篇文章主要介紹了SpringBoot中的自定義線程池解析,實(shí)現(xiàn)自定義線程池重寫spring默認(rèn)線程池的方式使用的時(shí)候,只需要加@Async注解就可以,不用去聲明線程池類,需要的朋友可以參考下
    2023-11-11
  • Java switch()括號(hào)內(nèi)參數(shù)的類型要求詳解

    Java switch()括號(hào)內(nèi)參數(shù)的類型要求詳解

    這篇文章主要介紹了Java switch()括號(hào)內(nèi)參數(shù)的類型要求,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot實(shí)現(xiàn)分頁功能

    SpringBoot實(shí)現(xiàn)分頁功能

    這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)分頁功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java內(nèi)省實(shí)例解析

    Java內(nèi)省實(shí)例解析

    這篇文章主要介紹了Java內(nèi)省實(shí)例解析,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • IDEA實(shí)用好用插件推薦及使用方法教程詳解(必看)

    IDEA實(shí)用好用插件推薦及使用方法教程詳解(必看)

    這篇文章主要介紹了IDEA實(shí)用好用插件推薦及使用方法教程,本文通過實(shí)例截圖相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論