Springboot整合Quartz定时任务框架(Spring解决方案)

news2024/12/24 0:59:35

目录

前言

介绍

集成

POM依赖

基础配置

1、配置数据源

2、配置JOB实例与触发器

3、配置SchedulerJobFactory

4、配置SchedulerFactoryBean

业务集成

job编写

接口编写 

接口实现


前言

系统现在有定时任务触发业务场景的需求,并且频率及次数不固定,即可以动态定义任务的频率及次数,因项目本身还是基于springboot开发,暂定还是使用Quartz,后期再升级,单独的Quartz配置有些问题,主要介绍springboot提供的集成方式。

介绍

多的不多,说一下quartz的表结构

 

  • QRTZ_BLOG_TRIGGERS    Trigger 作为 Blob 类型存储
  • QRTZ_CALENDARS    以 Blob 类型存储 Quartz 的 Calendar 信息
  • QRTZ_CRON_TRIGGERS    存储 Cron Trigger,包括 Cron 表达式和时区信息
  • QRTZ_FIRED_TRIGGERS    存储与已触发的 Trigger 相关的状态信息
  • QRTZ_PAUSED_TRIGGER_GRPS    存储已暂停的 Trigger 组的信息
  • QRTZ_SCHEDULER_STATE    存储少量的有关 Scheduler 的状态信息,和别的 Scheduler 实例
  • QRTZ_SIMPLE_TRIGGERS    存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
  • QRTZ_TRIGGERS    存储已配置的 Trigger 的信息
  • QRTZ_LOCKS    存储程序的非观锁的信息(假如使用了悲观锁)
  • QRTZ_JOB_DETAILS    存储每一个已配置的 Job 的详细信息

集成

废话不多说,直接开搞

POM依赖

使用springboot-starter的依赖


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

配置文件

基础配置

如果不想让业务的库客quartz的库在一起,可以这么做

1、配置数据源

@QuartzDataSource可以标记为quartz的库,配置数据源和事务管理器

@Configuration
public class SchedulerDataSourceConfig {

    private static final String QUARTZ_DATASOURCE = "spring.scheduler.datasource";

    @Bean
    @ConfigurationProperties(QUARTZ_DATASOURCE)
    public DataSourceProperties schedulerProperties() {
        return new DataSourceProperties();
    }

    @QuartzDataSource
    @Bean
    public DataSource quartzDataSource(DataSourceProperties schedulerProperties) {
        return schedulerProperties.initializeDataSourceBuilder().build();
    }

    @Bean
    public PlatformTransactionManager transactionManager(@Qualifier("quartzDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

配置文件:

spring:
  scheduler:
    datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://***/quartz
      username: root
      password: ****
      type: com.mysql.cj.jdbc.MysqlDataSource
  quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: always
      comment-prefix: #
    properties:
      org:
        quartz:
          jobStore:
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #我们仅为数据库制作了特定于数据库的代理
            useProperties: false #以指示JDBCJobStore将JobDataMaps中的所有值都作为字符串,因此可以作为名称 - 值对存储而不是在BLOB列中以其序列化形式存储更多复杂的对象。从长远来看,这是更安全的,因为您避免了将非String类序列化为BLOB的类版本问题。
            tablePrefix: scheduler_  #数据库表前缀
            misfireThreshold: 60000 #在被认为“失火”之前,调度程序将“容忍”一个Triggers将其下一个启动时间通过的毫秒数。默认值(如果您在配置中未输入此属性)为60000(60秒)。
            clusterCheckinInterval: 5000 #设置此实例“检入”*与群集的其他实例的频率(以毫秒为单位)。影响检测失败实例的速度。
            isClustered: true #打开群集功能
          threadPool: #连接池
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 4
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true

2、配置JOB实例与触发器

JobDetailFactoryBean 是spring退出的quartz解决方案,用来产生job。

SpringBoot触发器分类分别为 

SimpleTriggerFactoryBean:简单触发器,通过配置间隔时间实现

CronTriggerFactoryBean:  cron触发器,key通过配置cron表达式来实现

@Configuration
public class JobConfig {

    @Bean
    JobDetailFactoryBean dailyJob() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(DailyJobExecutor.class);
        bean.setDurability(true);
        return bean;
    }

    @Bean
    CronTriggerFactoryBean dailyTrigger(@Qualifier("dailyJob") JobDetail jobDetail) {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setJobDetail(jobDetail);
        //cron 每日一次
        bean.setCronExpression("0 0 0 * * ?");
        return bean;
    }

    
    @Bean
    SimpleTriggerFactoryBean simpleTrigger(@Qualifier("dailyJob") JobDetail jobDetail) {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setJobDetail(jobDetail);
        //多少秒一次
        bean.setRepeatInterval(5000L);
        bean.setStartDelay(5000L);
        return bean;
    }
}

3、配置SchedulerJobFactory

因为我们最终写的job对象最终是new出来quartz管理的,如果在里面使用 @Autowired等spring的注解不会生效,所以配置spring工厂,把实例交给spring管理

@Component
public class SchedulerJobFactory extends SpringBeanJobFactory {

    @Resource
    private AutowireCapableBeanFactory capableBeanFactory;

    @NotNull
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入(Spring管理该Bean)
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

4、配置SchedulerFactoryBean

定时工厂,将我们配置的触发器、数据源、job工厂都注入进来

@Configuration
public class SchedulerConfig {

    @javax.annotation.Resource
    private List<CronTriggerFactoryBean> cronTriggerFactoryBeans;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean (@Qualifier("quartzDataSource") DataSource dataSource,
                                                      @Qualifier("schedulerJobFactory") JobFactory jobFactory,
                                                      @Qualifier("quartzTransactionManager")PlatformTransactionManager transactionManager) throws Exception {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setBeanName("order-scheduler");
        schedulerFactoryBean.setDataSource(dataSource);
        Resource resource = new PathMatchingResourcePatternResolver()
                .getResources("classpath*:/application-scheduler.yml")[0];
        schedulerFactoryBean.afterPropertiesSet();
        schedulerFactoryBean.setConfigLocation(resource);
        schedulerFactoryBean.setJobFactory(jobFactory);
        schedulerFactoryBean.setTransactionManager(transactionManager);
        schedulerFactoryBean.setTriggers();
        CronTrigger[] triggers = cronTriggerFactoryBeans.stream().map(CronTriggerFactoryBean::getObject).toArray(CronTrigger[]::new);

        schedulerFactoryBean.setTriggers(triggers);
        return schedulerFactoryBean;
    }
}

业务集成

job编写

上面JobConfig里面配置的job执行类,因为我用的触发器为cron触发,频率为每天一次,因此为了解耦,每个需要每天执行的job都可以使用这个,注入了接口 DailyJobService, 有多个实现

@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
@Component
public class DailyJobExecutor extends QuartzJobBean {

    @Resource
    private List<DailyJobService> dailyJobServiceList;

    @Override
    protected void executeInternal(JobExecutionContext context) {

        log.info("dailyJobService  start...");
        dailyJobServiceList.forEach(DailyJobService::execute);
    }
}

接口编写 

DailyJobService,里面定义了执行方法

@Service
public interface DailyJobService {

    void execute();
}

接口实现

里面写具体的业务逻辑

@Slf4j
@Service
public class OralTackJobServiceImpl implements DailyJobService {


    @Override
    public void execute() {


        log.info("OralTackJobServiceImpl start....");

        //业务逻辑
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/443087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【案例教程】FVCOM流域、海洋水环境数值模拟方法及实践技术应用

近年来&#xff0c;随着人类活动产生营养负荷的增加&#xff0c;流域、海洋生态系统面临严重威胁。近岸水质数值模是近岸水环境保护的有效工具&#xff0c;已经应用于近岸水环境污染控制、水质规划管理中。FVCOM在近岸水环境模拟方面具有一定优势&#xff0c;如采用非结构化三角…

王道计组(23版)2_数据的表示和运算

1.数制和编码 十进制转换为二进制&#xff1a; 原码&#xff1a; [0]原0,0000 [-0]原1,0000 -1无法表示 补码&#xff1a; 按位取反&#xff0c;末位加1 [0.0000]补[-0.0000]补0.00000 反码&#xff1a; 按位取反 [0]反0,0000 [-0]反1,1111 移码&#xff1a; 与补码仅符号位…

从前端角度快速理解Transformer

从前端角度快速理解Transformer Transformer的三步曲从前端角度&#xff08;SEO和TDK&#xff09;理解TransformerSEO与TDK一个例子来理解 总结 声明&#xff1a;本文为原创&#xff0c;未经同意请勿转载或爬取&#xff0c;感谢配合&#x1f604; chatGPT今年年初的时候是非常火…

操作系统实验一 并发程序设计

1.实验目的 掌握Linux环境下&#xff0c;多进程之间并发程序设计方法&#xff0c;并通过程序的运行结果来验证分时系统和并发程序设计的优越性。 2.实验要求 熟悉Linux操作系统子进程创建方法以及任务执行时间测量方法 3.实验内容 在单进程&#xff08;单用户、单任务&#xff…

【MYSQL索引失效的场景有哪些】

创建一张表&#xff1a;id为主键&#xff08;primary key&#xff09;name为普通建&#xff08;index&#xff09; 插入数据&#xff1a; 用主键索引查询&#xff1a; 用普通建索引查询 对于执行计划&#xff0c;参数有&#xff1a; possible_keys 字段表示可能用到的索引&am…

KMM初探与编译过程详解

本文字数&#xff1a;22817字 预计阅读时间&#xff1a;58分钟 简介 KMM&#xff0c; 即Kotlin Multiplatform Mobile&#xff0c;是由Kotlin发布的移动端跨平台框架。相比于其他跨平台框架&#xff0c;KMM是原生UI逻辑共享的理念&#xff0c;共享重复逻辑性的工作来提升开发效…

Maven配置国内源以及jar下载失败处理详解

目录 1&#xff0c;配置Idea的Maven xml文件不存在&#xff1a; xml文件存在&#xff1a; 2&#xff0c;重新下载jar包 3&#xff0c;注意事项总结 1&#xff0c;配置Idea的Maven 需要配置的项目有两个&#xff0c;一个是当前项目&#xff0c;一个是新项目&#xff1a; 打…

抖音账号矩阵搭建管理获客系统

抖音矩阵号管理系统是一款企业矩阵运营管理工具&#xff0c;能够有效地帮助企业管理多个矩阵账号&#xff0c;并实现批量管理。在短视频矩阵系统中&#xff0c;自动获客工具和智能AI的帮助下&#xff0c;一个人也能轻松地管理多个账号。 一、矩阵账号管理&#xff1a; 首先&a…

leetCode算法第三天

继续练习leetcode中关于字符串的算法题&#xff0c;越练越觉得自己编码思想还很欠缺&#xff0c;继续努力。 文章目录 有效的括号括号生成串联所有单词的子串最长有效括号 有效的括号 leetcode链接&#xff1a;https://leetcode.cn/problems/valid-parentheses/ 解题思路&…

SPI协议

SPI数据接口 SPI&#xff08;Serial Peripheral Interface&#xff09;串行外设接口的简称&#xff0c;它是一种同步全双工通信协议。有 3根或者 4根数据线组成&#xff0c;包括 CLK、SOMI、SIMO、STE&#xff1a; CLK为时钟线&#xff0c;由主机控制输出。 SOMI…

国产数字温度传感芯片M117 Pin to Pin替代PT100和PT1000

高精度数字温度传感芯片 - M117&#xff0c;可Pin to Pin替代PT100/PT1000&#xff0c;且具功能差异化优势&#xff0c;支持行业应用的定制化需求。高测温精度0.1℃&#xff0c;用户无需进行校准。芯片感温原理基于CMOS半导体PN节温度与带隙电压的特性关系&#xff0c;经过小信…

电脑开机进不了系统卡在加载界面怎么办?

电脑开机进不了系统卡在加载界面怎么办&#xff1f;有用户电脑弹出需要进行系统更新&#xff0c;不小心点到了系统更新的选项。因为自己不想进行系统更新&#xff0c;所以马上将电脑关机了。但是关机之后却发现系统一直卡在开机的界面中&#xff0c;无法进入桌面中了。那么这个…

如何在Anaconda下安装pytorch(conda安装和pip安装)

前言 文字说明 本文中标红的&#xff0c;代表的是我认为比较重要的。 版本说明 python环境配置&#xff1a;jupyter的base环境下的python是3.10版本。CUDA配置是&#xff1a;CUDA11.6。目前pytorch官网提示支持的版本是3.7-3.9 本文主要用来记录自己在安装pytorch中…

乙肝80%以上由妈妈传给孩子 5岁以下治愈率超六成

中国是乙肝大国。目前&#xff0c;乙肝病毒感染人数仍超过7000万。通过医务人员多年的努力&#xff0c;母婴传播感染率明显下降。到目前为止&#xff0c;已降至0.3%左右。每年仍有5万名儿童感染乙肝病毒。目前&#xff0c;儿童慢性乙肝仍在180万左右&#xff0c;绝对数仍是世界…

Node【模块系统】

文章目录 &#x1f31f;前言&#x1f31f;Nodejs模块系统&#x1f31f;为什么需要模块化&#x1f31f;什么是Nodejs模块&#x1f31f;Nodejs模块分类&#x1f31f;文件模块的分类&#x1f31f;调用内置模块&#x1f31f;调用文件模块 &#x1f31f;Nodejs模块使用&#x1f31f;…

2023年网络安全的发展趋势是怎样的?

数据安全越来越重要。 我国《数据安全法》提出“建立健全数据安全治理体系”&#xff0c;各地区部门均在探索和简历数据分类分级、重要数据识别与重点保护制度。 数据安全治理不仅是一系列技术应用或产品&#xff0c;更是包括组织构建、规范制定、技术支撑等要素共同完成数据…

PACS/RIS影像管理系统源码,支持图像后处理与重建

PACS/RIS影像管理系统源码&#xff0c;功能强大&#xff0c;文档齐全&#xff0c;有演示。 文末获取联系&#xff01; 系统特点&#xff1a; 符合国内医院影像中心/放射科的典型工作管理流程。 开放式体系结构&#xff0c;完全符合DICOM3.0标准&#xff0c;提供HL7标准接口&a…

MyBatis(十四)MyBatis的逆向工程

前言、 所谓的逆向工程是&#xff1a;根据数据库表逆向生成Java的pojo类&#xff0c;SqlMapper.xml文件&#xff0c;以及Mapper接口类等。 要完成这个工作&#xff0c;需要借助别人写好的逆向工程插件。 思考&#xff1a;使用这个插件的话&#xff0c;需要给这个插件配置哪些…

2023年淮阴工学院五年一贯制专转本退役士兵大学语文考试大纲

2023年淮阴工学院五年一贯制专转本退役士兵大学语文考试大纲 一、考试目标 淮阴工学院五年一贯制高职专转本入学考试秘书学专业《大学语文》考试是我校为招收五年一贯制高职专转本学生设置的具有选拔性质的考试科目。其目的是科学、公平、有效地测试考生是否具备攻读秘书学本…

【论文总结】V-Shuttle:可扩展和语义感知的 Hypervisor 虚拟设备模糊测试

介绍 这是来自2021 CCS的一篇论文&#xff0c;作者有GaoningPan, Xingwei Lin, Xuhong Zhang, Yongkang Jia, Shouling Ji, Chunming Wu, Xinlei Ying, Jiashui Wang, Yanjun Wu。该论文提出V-shuttle的新框架来执行管控程序的模糊测试&#xff0c;该框架执行可扩展和语义感知…