springboot集成quartz

这篇具有很好参考价值的文章主要介绍了springboot集成quartz。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

引用上一篇博客的说法 springboot整合xxl-job ,集群模式下,定时任务会造成很严重的事故,其次普通的任务也无法做到像xxl-job与Quartz 一样,及时启停,修改等;上一篇介绍了xxl-job,这篇搞一下Quartz,老牌分布式定时任务了;


一、Quartz是什么?

比较详细的Quartz文档

难易程度

Quartz 并没有给出明确的例子,但是文档详细,且任务的操作简单明了,步骤清晰,本身是可以脱离Spring-boot 单独工作的,而且可以更高度自定义话。需要自己摸搜整合,一般还需要自己维护数据库的表等,为了任务的添加做参数等;
xxl-job 官方提供了springboot以及普通项目集成demo,所以在集成方面,只要理解了它的思想xxl-job集成很快,数据库等都是现有的,导入即可;但是封装较深,尤其分为了服务端与客户端,无形增加了服务数量,且通信之间还有可能有通信信息丢失情况等;

二、核心思想

  1. Quartz 的调度中心是Scheduler,所以只要将任务交给它就行了
  2. 一个通用的任务是JobDetail,用来接受各种具体的任务逻辑
  3. CronTrigger 是JobDetail 的触发条件,所以Scheduler需要的是 JobDetail 任务和CronTrigger 任务触发器
  4. JobDetail既然是通用任务,用于接受任务,所以我们要定义一个自己的任务类(例如叫做QuartzJob),这个任务类需要实现 Job接口
  5. 这个任务类QuartzJob,要执行具体的任务,具体的任务,一般都是我们需要自己的一些方法,
    例如: 每天晚上12点执行一次清理数据库之前的数据; 一般我们会写一个这样的方法
    public class LogImpl implements LogService{
    	public void clear(){
    		logService.remove(new Date());
    	}
    }
    
    那么QuartzJob中其实就要执行LogImpl 这个类中的 clear()这个方法,这里通过反射执行;
    6. 因为我们一般都会在数据库中加入 LogImpl 这个类中的 clear()这个方法,然后交给Quartz执行,所以只能通过反射执行

三、使用步骤

1.引入依赖

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

2.创建相应类

  1. QuartzUtil 此类作为操作job的工具类,这里的job与quartz中的 JobDetail一一对应 ,包括任务的增删改
public class QuartzUtil {

    /**
     * 将新增的任务放入quartz调度中心中执行
     *
     * @param sysJob 具体任务信息
     * @throws Exception 异常
     */
    @SneakyThrows
    public static void insertOrUpdateJob(SysJob sysJob) {
        // 获取调度器 Scheduler
        Scheduler scheduler = SchedulerStatic.getScheduler();
        Long jobId = sysJob.getJobId();
        String jobGroup = sysJob.getJobGroup();

        // 构造一个job
        JobKey jobKey = JobKey.jobKey(jobId.toString(), jobGroup);
        JobDetail jobDetail = JobBuilder
                .newJob(QuartzJob.class)
                .withIdentity(jobKey)
                .build();

        // 构造cron调度器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(sysJob.getCronExpression());
        getMisfirePolicy(sysJob, cronScheduleBuilder);

        // 构造触发器 trigger
        TriggerKey triggerKey = TriggerKey.triggerKey(jobId.toString(), jobGroup);
        CronTrigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity(triggerKey)
                .withSchedule(cronScheduleBuilder)
                .build();

        // 放入job信息,为后续执行改任务的具体方法做铺垫(需要反射调用), 在execute中获取并应用
        jobDetail.getJobDataMap().put(QuartzEnum.jobKey, sysJob);
        // 判断该任务是否存在,修改任务,先删除然后添加
        if (scheduler.checkExists(jobKey)) {
            // 防止创建时存在数据问题 先移除,然后在执行创建操作
            scheduler.deleteJob(jobKey);
        }
        // 判断任务是否过期
        CronExpression cron = new CronExpression(sysJob.getCronExpression());
        Date nextValidTimeAfter = cron.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
        if (!ObjectUtils.isEmpty(nextValidTimeAfter)) {
            // 执行调度任务
            scheduler.scheduleJob(jobDetail, trigger);
        }
        // 暂停任务
        if (sysJob.getStatus().equals(QuartzEnum.PAUSE)) {
            scheduler.pauseJob(jobKey);
        }
    }


    /**
     * 根据计划执行错误策略,设置调度器
     *
     * @param sysJob              任务信息
     * @param cronScheduleBuilder cron调度器
     */
    private static void getMisfirePolicy(SysJob sysJob, CronScheduleBuilder cronScheduleBuilder) {
        switch (sysJob.getMisfirePolicy()) {
            case QuartzEnum.MISFIRE_DEFAULT:
                break;
            case QuartzEnum.MISFIRE_IGNORE_MISFIRES:
                cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires();
                break;
            case QuartzEnum.MISFIRE_FIRE_AND_PROCEED:
                cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed();
                break;
            case QuartzEnum.MISFIRE_DO_NOTHING:
                cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();
                break;
            default:
                throw new RuntimeException("The task misfire policy '" + sysJob.getMisfirePolicy() + "' cannot be used in cron schedule tasks");
        }
    }

    /**
     * 删除任务
     *
     * @param sysJob 具体任务信息(获取jobkey)
     */
    @SneakyThrows
    public static void deleteJob(SysJob sysJob) {
        // 获取调度器 Scheduler
        Scheduler scheduler = SchedulerStatic.getScheduler();
        scheduler.deleteJob(JobKey.jobKey(sysJob.getJobId().toString(), sysJob.getJobGroup()));
    }
}
  1. QuartzJob
    1. 此类作为所有任务的执行入口,其他要执行的具体逻辑应该注入spring,然后通过此 通过反射调用到具体任务执行类
    1. sysJob包含着要执行的具体逻辑类的信息,以及方法,参数等信息,此案例维护在数据库中
    1. 通过更改数据库数据,动态变更quartz中的任务
    1. 目前仅仅做了无参构造器的方法执行,后续补充
public class QuartzJob implements Job {

   @Override
   public void execute(JobExecutionContext context) throws JobExecutionException {
       // 获取任务执行参数
       SysJob sysJob = (SysJob) context.getJobDetail().getJobDataMap().get(QuartzEnum.jobKey);

       // invokeTarget 应该符合 类.方法名 例如 task.sout()
       String invokeTarget = sysJob.getInvokeTarget();
       String beanName = invokeTarget.split("\\.")[0];
       String temp = invokeTarget.split("\\.")[1];
       String methodName = temp.substring(0, temp.indexOf("("));

       Object bean = SpringUtil.getBean(beanName);
       Method method = null;
       try {
           method = bean.getClass().getMethod(methodName);
           method.invoke(bean);
       } catch (Exception e) {
           e.printStackTrace();
           throw new RuntimeException(e);
       }
   }
}
  1. SchedulerStatic 此类仅仅作为引入静态调度器的工具类
@Component
public class SchedulerStatic {

    private static Scheduler scheduler;

    @Autowired
    public SchedulerStatic(Scheduler scheduler) {
        SchedulerStatic.scheduler = scheduler;
    }

    public static Scheduler getScheduler() {
        return scheduler;
    }
}

  1. MyTask
    . 此类作为具体执行任务的示例类
  • 此类应该注入spring容器中,为了后去获取方便,且一般业务都需要查询数据,所以此类比较常见
  • 如果非bean,那么 {@link com.example.springbootquartz.quartz.QuartzJob}.中需要自己扩展获取目标类 利用Class.forName()
@Service("task")
public class MyTask {

    @Autowired
    SysJobService sysJobService;

    /**
     * 任务的具体执行逻辑写在此处,这里只做打印
     */
    public void sout() {
        List<SysJob> list = sysJobService.list();
        list.forEach(sysJob -> System.out.println(sysJob.toString()));
    }
}
  1. yml 配置文件
    集成了swagger mp mysql quartz等
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/quartz?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
    username: root
    password: root

  # 页面配置
  mvc:
    path match:
      matching-strategy: ant_path_matcher
server:
  port: 8889

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  1. 通过接口文档地址,操作任务,达到动态更改分布式任务的效果
  • 直接访问控制台打印的地址即可
    springboot集成quartz,springboot,spring boot,java,后端
  • 通过添加任务的详细信息,查看任务执行情况
    springboot集成quartz,springboot,spring boot,java,后端
    可以看到,已经开始执行任务了,0/2 * * * * ? 每两秒后执行一次
    执行的是打印
    springboot集成quartz,springboot,spring boot,java,后端

总结

基本实现了任务的动态添加
后续完善:

  • 有参数的具体任务调用,修改QuartzJob中的方法获取,参数获取等,但是依旧采用代理实现
  • 任务并发执行未处理,后续完善

项目地址: springboot-quartz文章来源地址https://www.toymoban.com/news/detail-664105.html

到了这里,关于springboot集成quartz的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot 集成 Quartz + MySQL

    Quartz 简单使用 Java SpringBoot 中,动态执行 bean 对象中的方法 源代码地址 = https://gitee.com/VipSoft/VipBoot/tree/develop/vipsoft-quartz 只要配置好 DataSource Quartz 会自动进行表的数据操作, 添加 Quartz Job 任务 保存 QRTZ_JOB_DETAILS、QRTZ_TRIGGERS = QRTZ_CRON_TRIGGERS 详见: org.quartz.impl.jdbcjobstore.StdJD

    2023年04月18日
    浏览(32)
  • SpringBoot3集成Quartz

    目录 一、简介 二、工程搭建 1、工程结构 2、依赖管理 3、数据库 4、配置文件 三、Quartz用法 1、初始化加载 2、新增任务 3、更新任务 4、暂停任务 5、恢复任务 6、执行一次 7、删除任务 8、任务执行 四、参考源码 标签:Quartz.Job.Scheduler; Quartz由Java编写的功能丰富的开源作业

    2024年02月13日
    浏览(40)
  • spring boot集成Elasticsearch-SpringBoot(25)

      搜索引擎(search engine )通常意义上是指:根据特定策略,运用特定的爬虫程序从互联网上搜集信息,然后对信息进行处理后,为用户提供检索服务,将检索到的相关信息展示给用户的系统。   而我们讲解的是捜索的索引和检索,不涉及爬虫程序的内容爬取。大部分公司

    2023年04月09日
    浏览(110)
  • 【后端-Quartz】Springboot整合Quartz支持集群环境-设计业务与框架分离及实现定时任务调度

    我们的各个服务需要改造支持集群,现在的授权、日程使用的是基于内存的spring scheduler定时任务,如果部署多个节点,那么到了时间点,多个节点都会开始执行定时任务从而可能引起业务和性能上的问题。 服务中的定时任务比较轻量,为了避免引入redis、zookeeper、单独的定时

    2023年04月09日
    浏览(42)
  • 【SpringBoot3】Spring Boot 3.0 集成 Redis 缓存

    Redis缓存是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它主要用于作为数据库、缓存和消息中间件,以快速读写和丰富的数据结构支持而著称。 在应用程序和数据库之间,Redis缓存作为一个中间层起着关键

    2024年02月21日
    浏览(52)
  • spring boot学习第六篇:SpringBoot 集成WebSocket详解

    1、WebSocket简介 WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 2、为什么需要WebSocket HTTP 是基于请求响应式的,即通信只能由客户端发起,服务端做出响应,无状态,无连接。 无状态:每次连

    2024年01月21日
    浏览(50)
  • SpringBoot - 集成Quartz框架之常用配置

    Quartz是一款Java编写的 开源任务调度框架 ,同时它也是Spring默认的任务调度框架。它的作用其实类似于Java中的Timer定时器以及JUC中的ScheduledExecutorService调度线程池,当然Quartz作为一个独立的任务调度框架无疑在这方面表现的更为出色,功能更强大,能够定义更为复杂的执行规

    2024年02月13日
    浏览(32)
  • SpringBoot(二)集成 Quartz:2.5.4

    Quartz是一个广泛使用的开源任务调度框架,用于在Java应用程序中执行定时任务和周期性任务。它提供了强大的调度功能,允许您计划、管理和执行各种任务,从简单的任务到复杂的任务。 以下是Quartz的一些关键特点和功能: 灵活的调度器:Quartz提供了一个高度可配置的调度

    2024年02月07日
    浏览(35)
  • 【SpringBoot】83、SpringBoot集成Quartz实现调度日志收集

    1、Quartz简介 Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵 活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB 作业预构 建,JavaMail 及

    2024年02月11日
    浏览(58)
  • SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接

    系列文章: SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计 SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接 SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接 SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现 SpringBoot + Vue前后

    2024年02月12日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包