精华内容
下载资源
问答
  • springboot集成quartz
    2022-07-15 11:48:59

    https://blog.csdn.net/weixin_38192427/article/details/121111677

    我的其他文章

    亲身分享 一次 字节跳动 真实面试经历和面试题

    我的网站

    字节小柜:http://82.157.190.245/

    更多相关内容
  • springboot集成quartz

    2021-12-12 00:09:13
    springboot集成quartz Spring Boot 集成 Quartz 定时任务,并实现对定时任务的管理,包括新增定时任务,删除定时任务,暂停定时任务,恢复定时任务,修改定时任务启动时间,以及定时任务列表查询。 代码地址:...

    springboot集成quartz

    Spring Boot 集成 Quartz 定时任务,并实现对定时任务的管理,包括新增定时任务,删除定时任务,暂停定时任务,恢复定时任务,修改定时任务启动时间,以及定时任务列表查询。

    代码地址:https://github.com/DNYDYS/spring-boot-quartz.git

    后端

    初始化

    init/dbTables 下选择 Quartz 需要的表结构,然后手动创建表。

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>spring-boot-demo-task-quartz</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>spring-boot-demo-task-quartz</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>com.dnydys</groupId>
            <artifactId>spring-boot-demo</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <mybatis.mapper.version>2.1.0</mybatis.mapper.version>
            <mybatis.pagehelper.version>1.2.10</mybatis.pagehelper.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
            </dependency>
    
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${mybatis.mapper.version}</version>
            </dependency>
    
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${mybatis.pagehelper.version}</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>spring-boot-demo-task-quartz</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    application.yml

    server:
      port: 9080
      servlet:
        context-path: /demo
    spring:
    # 省略其余配置,具体请 clone 本项目,查看详情
    # ......
      quartz:
        # 参见 org.springframework.boot.autoconfigure.quartz.QuartzProperties
        job-store-type: jdbc
        wait-for-jobs-to-complete-on-shutdown: true
        scheduler-name: SpringBootDemoScheduler
        properties:
          org.quartz.threadPool.threadCount: 5
          org.quartz.threadPool.threadPriority: 5
          org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
          org.quartz.jobStore.misfireThreshold: 5000
          org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
          org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
          # 在调度流程的第一步,也就是拉取待即将触发的triggers时,是上锁的状态,即不会同时存在多个线程拉取到相同的trigger的情况,也就避免的重复调度的危险。参考:https://segmentfault.com/a/1190000015492260
          org.quartz.jobStore.acquireTriggersWithinLock: true
    
    # ......
    

    前端

    <div id="job">
        <div id="top">
            <el-button size="small" type="primary" plain @click="search" :loading="loading" icon="el-icon-search">查询
            </el-button>
            <el-button size="small" type="primary" plain @click="handleadd" icon="el-icon-plus">添加</el-button>
        </div>
        <br/>
        <div>
            <el-table ref="jobTable" :data="tableData" style="width:100%" border center>
                <el-table-column prop="jobName" label="任务名称" show-overflow-tooltip align="center"></el-table-column>
                <el-table-column prop="jobGroup" label="任务所在组" sortable align="center"></el-table-column>
                <el-table-column prop="jobClassName" label="任务类名" align="center"></el-table-column>
                <el-table-column prop="triggerName" label="触发器名称" align="center"></el-table-column>
                <el-table-column prop="triggerGroup" label="触发器所在组" sortable align="center"></el-table-column>
                <el-table-column prop="cronExpression" label="表达式" align="center"></el-table-column>
                <el-table-column prop="timeZoneId" label="时区" align="center"></el-table-column>
                <el-table-column prop="triggerState" label="状态" align="center" :formatter="formatState"></el-table-column>
                <el-table-column label="操作" width="300" align="center">
                    <template scope="scope">
                        <el-button size="small" type="warning" @click="handlePause(scope.$index, scope.row)">
                            暂停
                        </el-button>
                        <el-button size="small" type="info" @click="handleResume(scope.$index, scope.row)">
                            恢复
                        </el-button>
                        <el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">
                            删除
                        </el-button>
                        <el-button size="small" type="success" @click="handleUpdate(scope.$index, scope.row)">
                            修改
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
    
            <div align="center">
                <el-pagination
                        @size-change="handleSizeChange"
                        @current-change="handleCurrentChange"
                        :current-page="currentPage"
                        :page-sizes="[10, 20, 30, 40]"
                        :page-size="pagesize"
                        layout="total, sizes, prev, pager, next, jumper"
                        :total="totalCount">
                </el-pagination>
            </div>
        </div>
    
        <el-dialog title="添加任务" :visible.sync="dialogFormVisible">
            <el-form :model="form">
                <el-form-item label="任务名称" label-width="100px" style="width:90%">
                    <el-input v-model="form.jobName" auto-complete="off"></el-input>
                </el-form-item>
                <el-form-item label="任务分组" label-width="100px" style="width:90%">
                    <el-input v-model="form.jobGroup" auto-complete="off"></el-input>
                </el-form-item>
                <el-form-item label="表达式" label-width="100px" style="width:90%">
                    <el-input v-model="form.cronExpression" auto-complete="off"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消</el-button>
                <el-button type="primary" @click="add">确 定</el-button>
            </div>
        </el-dialog>
    
        <el-dialog title="修改任务" :visible.sync="updateFormVisible">
            <el-form :model="updateform">
                <el-form-item label="表达式" label-width="100px" style="width:90%">
                    <el-input v-model="updateform.cronExpression" auto-complete="off"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="updateFormVisible = false">取 消</el-button>
                <el-button type="primary" @click="update">确 定</el-button>
            </div>
        </el-dialog>
    </div>
    

    启动

    1. clone 本项目
    2. 初始化表格
    3. 启动 SpringBootDemoTaskQuartzApplication.java
    4. 打开浏览器,查看 http://localhost:9080/demo/job.html
      在这里插入图片描述
    com.xkcoding.task.quartz.job.HelloJob
    
    HelloJob
    
    */6 * * * * ?
    

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    参考

    • Spring Boot 官方文档:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-quartz

    • Quartz 官方文档:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/quick-start.html

    • Quartz 重复调度问题:https://segmentfault.com/a/1190000015492260

    • 关于Quartz定时任务状态 (在 QRTZ_TRIGGERS 表中的 TRIGGER_STATE 字段)

    • Vue.js 官方文档:https://cn.vuejs.org/v2/guide/

    • Element-UI 官方文档:http://element-cn.eleme.io/#/zh-CN
      ![请添加图片描述](https://img-blog.csdnimg.cn/f8a12183a75f4aa4a21c82b5e29ef107.jpg?x-oss-请添加图片描述
      process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBARE5ZRFlT,size_20,color_FFFFFF,t_70,g_se,x_16)

    展开全文
  • SpringBoot集成Quartz完全分布式定时任务,即插即用,不好用直接捶我! SpringBoot集成Quartz分布式定时任务 SpringBoot集成Quartz分布式定时任务
  • Springboot集成quartz集群

    2018-09-29 16:39:28
    本文章是关于springboot集成quartz集群的步骤,LZ亲测。
  • springboot 集成 quartz 集群 加 sql 等 文章介绍 单机加集群都有 https://blog.csdn.net/weixin_42749765/article/details/88532413
  • Springboot集成Quartz

    千次阅读 2021-12-16 20:04:51
    Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的...创建一个简单的SpringBoot项目,pom如下: <?xml version="1.0" encoding="UTF-8"?> <project xm.

    Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。该文章不过多介绍Quartz的概念,主要做一个封装的记录。

    功能点

    1. 添加CRON、固定间隔定时
    2. 修改定时的触发器
    3. 修改定时参数
    4. 暂停定时
    5. 启动暂停的定时
    6. 获取所有定时
    7. 启动所有定时
    8. 停止定时

    0. 创建项目

    创建一个简单的SpringBoot项目,pom如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.1</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>org.demo</groupId>
        <artifactId>quartz</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>quartz</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>11</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    

    1. 定时类型

    Quartz可以通过org.quartz.Trigger.class去拓展定时类型的,目前需求需要支持CRON和固定间隔两种定时类型,后期需要支持跳过节假日、周一~周五、周末等需求,所以需要让定时类型支持拓展。

    1.1定时类型

    package org.demo.quartz.mode;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName TimingTriggerType.java
     * @Description 定时类型触发器类型
     * @createTime 2021年12月16日
     */
    public enum TriggerType {
        CRON("标准CRON支持"),
        INTERVAL_MILLISECOND("固定间隔毫秒"),
        INTERVAL_SECOND("固定间隔秒"),
        INTERVAL_MINUTE("固定间隔分钟"),
        INTERVAL_HOUR("固定间隔小时"),
        WEEKDAYS("工作日,跳过节假日"),
        HOLIDAY("节假日")
        ;
    
    
        private String describe;
    
        TriggerType(String describe) {
            this.describe = describe;
        }
    }
    

    1.2 构建定时任务的抽象类

    我们需要构建不同的定时类型,不同的定时类型需要的参数也是不同的,因此我们需要抽象出定时的公用参数,将不同的参数多态实现。

    package org.demo.quartz.mode;
    
    import lombok.Getter;
    import lombok.Setter;
    import org.demo.quartz.task.QuartzTaskJob;
    
    import java.util.Map;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName TimingModel.java
     * @Description 构建定时的model
     * @createTime 2021年12月16日
     */
    @Getter
    @Setter
    public class TimingModel {
        /**
         * 该定时的任务处理器
         */
        private Class<? extends QuartzTaskJob> taskClass;
    
        /**
         * 任务名
         */
        private String taskName;
        /**
         * 任务组名
         * */
        private String groupName;
    
        /**
         * 任务描述
         * */
        private String description;
    
    
        /**
         * 任务类型
         */
        private TriggerType type;
    
    
        /**
         * 任务参数,可在具体的QuartzTaskJob实现中获取这些参数
         * */
        private Map<String, Object> param;
    
        /**
         * 任务状态
         * */
        private String taskStatus;
    
        public TimingModel(Class<? extends QuartzTaskJob> taskClass, String taskName, String groupName, String description, TriggerType type, Map<String, Object> param) {
            this.taskClass = taskClass;
            this.taskName = taskName;
            this.groupName = groupName;
            this.description = description;
            this.type = type;
            this.param = param;
        }
    
        public TimingModel(Class<? extends QuartzTaskJob> taskClass, String taskName, String groupName, String description, TriggerType type) {
            this.taskClass = taskClass;
            this.taskName = taskName;
            this.groupName = groupName;
            this.description = description;
            this.type = type;
        }
    }
    
    

    1.3 用以构建CRON定时任务

    package org.demo.quartz.mode;
    
    import lombok.Getter;
    import lombok.Setter;
    import org.demo.quartz.task.QuartzTaskJob;
    
    import java.util.Map;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName CronTimingModel.java
     * @Description cron触发器model
     * @createTime 2021年12月16日
     */
    @Getter
    @Setter
    public class CronTimingModel extends TimingModel{
        /**
         * cron表达式
         * */
        private String cronExpression;
    
        public CronTimingModel(Class<? extends QuartzTaskJob> taskClass, String taskName, String groupName, String description, Map<String, Object> param,String cronExpression) {
            super(taskClass, taskName, groupName, description, TriggerType.CRON, param);
            this.cronExpression = cronExpression;
        }
    
        public CronTimingModel(Class<? extends QuartzTaskJob> taskClass, String taskName, String groupName, String description,String cronExpression) {
            super(taskClass, taskName, groupName, description, TriggerType.CRON);
            this.cronExpression = cronExpression;
        }
    }
    

    1.4 用以构建固定间隔定时任务

    package org.demo.quartz.mode;
    
    import lombok.Getter;
    import lombok.Setter;
    import org.demo.quartz.exception.TimingException;
    import org.demo.quartz.task.QuartzTaskJob;
    
    import java.util.Map;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName IntervalTimingMode.java
     * @Description
     * @createTime 2021年12月16日
     */
    @Getter
    @Setter
    public class IntervalTimingMode extends TimingModel {
    
        /**
         * 事件间隔,根据TriggerType确定单位,除了数值为毫秒,该数值必须在-2^32~2^31   (-2147483648 ~ 2147483647)
         * */
        private Long interval;
    
        /**
         * 重复次数,会执行该数值+1次,为空无限重复
         * */
        private Integer repeatCount;
    
        public IntervalTimingMode(Class<? extends QuartzTaskJob> taskClass, String taskName, String groupName, String description, TriggerType type, Map<String, Object> param, Long interval,Integer repeatCount) {
            super(taskClass, taskName, groupName, description, type, param);
            if (type != TriggerType.INTERVAL_MILLISECOND){
                if (interval<(-2^32)||interval>(2^31)){
                    throw new TimingException("interval超出范围,除了类型为INTERVAL_MILLISECOND的数据间隔定时的interval范围必须在-2^32~2^31   (-2147483648 ~ 2147483647)");
                }
            }
            this.interval = interval;
            this.repeatCount = repeatCount;
        }
    
        public IntervalTimingMode(Class<? extends QuartzTaskJob> taskClass, String taskName, String groupName, String description, TriggerType type, Long interval,Integer repeatCount) {
            super(taskClass, taskName, groupName, description, type);
            if (type != TriggerType.INTERVAL_MILLISECOND){
                if (interval<(-2^32)||interval>(2^31)){
                    throw new TimingException("interval超出范围,除了类型为INTERVAL_MILLISECOND的数据间隔定时的interval范围必须在-2^32~2^31   (-2147483648 ~ 2147483647)");
                }
            }
            this.interval = interval;
            this.repeatCount = repeatCount;
        }
    }
    

    2.抽象任务类

    package org.demo.quartz.task;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName QuartzTaskJob.java
     * @Description
     * @createTime 2021年12月16日
     */
    public interface QuartzTaskJob extends Job {
        @Override
        void execute(JobExecutionContext context) throws JobExecutionException;
    }
    
    

    2.1 实现一个测试任务

    package org.demo.quartz.task;
    
    import lombok.extern.slf4j.Slf4j;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.SimpleTrigger;
    import org.springframework.stereotype.Component;
    
    @Component
    @Slf4j
    public class TestQuartz implements QuartzTaskJob {
    
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            // 获取参数
            JobDataMap jobDataMap = context.getTrigger().getJobDataMap();
            // 获取任务名
            String name = context.getJobDetail().getJobBuilder().build().getKey().getName();
            // 获取任务分组
            String group = context.getJobDetail().getJobBuilder().build().getKey().getGroup();
            // 获取任务描述
            String description = context.getJobDetail().getDescription();
            if (context.getTrigger() instanceof SimpleTrigger){
                // 运行次数
                System.out.println(((SimpleTrigger)context.getTrigger()).getTimesTriggered());
            }
            log.info("----------------------" +
                    "\n任务组:{}\n任务名:{}\n任务描述:{}\n获取参数paramKey:{}\n" +
                    "----------------------"
                    ,name,group,description,jobDataMap.getString("paramKey"));
    
            try {
    //            QuartzJobManager.getInstance().jobdelete(this.getClass().getSimpleName(),"ah");//执行完此任务就删除自己
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    3. 构建触发器的不同实现

    3.1 抽象触发器实现

    package org.demo.quartz.trigger;
    
    import org.demo.quartz.mode.TriggerType;
    import org.demo.quartz.mode.TimingModel;
    import org.quartz.Trigger;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName TriggerHandler.java
     * @Description 触发器工厂
     * @createTime 2021年12月16日
     */
    public interface ITriggerFactory {
    
        /**
         * 判断是否为该类型的触发器
         *
         * @param triggerType 触发器类型
         * @return boolean 如果是该类型的触发器返回true 否则返回false
         * @author YuanXiaohan
         * @date 2021/12/16 2:33 下午
         */
        public boolean check(TriggerType triggerType);
    
    
        public Trigger build(TimingModel timingModel);
    }
    
    

    3.2 CRON触发器

    package org.demo.quartz.trigger.factory;
    
    import org.demo.quartz.exception.TimingException;
    import org.demo.quartz.mode.CronTimingModel;
    import org.demo.quartz.mode.TriggerType;
    import org.demo.quartz.mode.TimingModel;
    import org.demo.quartz.trigger.ITriggerFactory;
    import org.quartz.CronScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName CronTrigger.java
     * @Description
     * @createTime 2021年12月16日
     */
    @Component
    public class CronTrigger implements ITriggerFactory {
        @Override
        public boolean check(TriggerType triggerType) {
            return triggerType==TriggerType.CRON;
        }
    
        @Override
        public Trigger build(TimingModel timingModel) {
            if (!(timingModel instanceof CronTimingModel)){
                throw new TimingException("构建类型为CRON定时必须传入CronTimingModel.class的实现类");
            }
            //按新的cronExpression表达式构建一个新的trigger
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(((CronTimingModel) timingModel).getCronExpression());
            return TriggerBuilder.newTrigger().withIdentity(timingModel.getTaskName(), timingModel.getTaskName())
                    .withSchedule(scheduleBuilder).build();
        }
    }
    
    

    3.3 固定间隔触发器

    package org.demo.quartz.trigger.factory;
    
    import org.demo.quartz.exception.TimingException;
    import org.demo.quartz.mode.IntervalTimingMode;
    import org.demo.quartz.mode.TimingModel;
    import org.demo.quartz.mode.TriggerType;
    import org.demo.quartz.trigger.ITriggerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName IntervalTrigger.java
     * @Description
     * @createTime 2021年12月16日
     */
    @Component
    public class IntervalTrigger implements ITriggerFactory {
        @Override
        public boolean check(TriggerType triggerType) {
            return triggerType == TriggerType.INTERVAL_MINUTE || triggerType == TriggerType.INTERVAL_SECOND || triggerType == TriggerType.INTERVAL_MILLISECOND||triggerType == TriggerType.INTERVAL_HOUR;
        }
    
        @Override
        public Trigger build(TimingModel timingModel) {
            if (!(timingModel instanceof IntervalTimingMode)){
                throw new TimingException("构建类型为INTERVAL定时必须传入IntervalTimingMode.class的实现类");
            }
            //创建触发器
            SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
            Long interval = ((IntervalTimingMode) timingModel).getInterval();
            Integer repeatCount = ((IntervalTimingMode) timingModel).getRepeatCount();
            switch (timingModel.getType()){
                case INTERVAL_MINUTE:
                    simpleScheduleBuilder.withIntervalInMinutes(Math.toIntExact(interval));
                    break;
                case INTERVAL_HOUR:
                    simpleScheduleBuilder.withIntervalInHours(Math.toIntExact(interval));
                    break;
                case INTERVAL_SECOND:
                    simpleScheduleBuilder.withIntervalInSeconds(Math.toIntExact(interval));
                    break;
                case INTERVAL_MILLISECOND:
                    simpleScheduleBuilder.withIntervalInMilliseconds(interval);
                    break;
            }
            if (repeatCount==null){
                // 无限重复
                simpleScheduleBuilder.repeatForever();
            }else {
                simpleScheduleBuilder.withRepeatCount(repeatCount);
            }
            return TriggerBuilder.newTrigger().withIdentity(timingModel.getTaskName(), timingModel.getTaskName())
                    .withSchedule(simpleScheduleBuilder).build();
        }
    }
    
    

    3.4 构建触发器工厂

    package org.demo.quartz.trigger;
    
    import org.demo.quartz.mode.TimingModel;
    import org.quartz.Trigger;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName TriggerManager.java
     * @Description 触发器管理器, 用来生成触发器
     * @createTime 2021年12月16日
     */
    @Component
    public class TriggerManager {
        private final List<ITriggerFactory> triggerFactories;
    
        public TriggerManager(List<ITriggerFactory> triggerFactories) {
            this.triggerFactories = triggerFactories;
        }
    
        /**
         * 生成对应的触发器
         *
         * @param timingModel 触发器model
         * @return org.quartz.Trigger
         * @author YuanXiaohan
         * @date 2021/12/16 2:53 下午
         */
        public Trigger build(TimingModel timingModel) {
            for (ITriggerFactory triggerFactory : triggerFactories) {
                if (triggerFactory.check(timingModel.getType())) {
                    return triggerFactory.build(timingModel);
                }
            }
            return null;
        }
    }
    
    

    3. 构建定时管理类

    该方法包含:

    1. 添加定时
    2. 更新定时触发器
    3. 更新任务参数
    4. 删除任务
    5. 暂停任务
    6. 将暂停的任务恢复执行
    7. 启动所有任务
    8. 关闭定时任务
    9. 获取所有任务
    package org.demo.quartz;
    
    import lombok.extern.slf4j.Slf4j;
    import org.demo.quartz.mode.CronTimingModel;
    import org.demo.quartz.mode.TimingModel;
    import org.demo.quartz.trigger.TriggerManager;
    import org.demo.quartz.exception.TimingException;
    import org.quartz.*;
    import org.quartz.impl.matchers.GroupMatcher;
    import org.springframework.context.annotation.Configuration;
    
    import java.lang.reflect.InvocationTargetException;
    import java.util.*;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName QuartzTaskManager.java
     * @Description
     * @createTime 2021年12月16日
     */
    @Configuration
    @Slf4j
    public class QuartzTaskManager {
    
        private final Scheduler scheduler;
    
        private final Boolean initStatus;
    
        private final TriggerManager triggerManager;
    
        private static QuartzTaskManager taskManager;
    
        public QuartzTaskManager(Scheduler scheduler, TriggerManager triggerManager) {
            this.scheduler = scheduler;
            taskManager = this;
            boolean status = true;
            try {
                // 启动调度器
                scheduler.start();
            } catch (SchedulerException e) {
                log.error("定时器调度器启动失败,定时器不可用!", e);
                status = false;
            }
            initStatus = status;
            this.triggerManager = triggerManager;
        }
    
        public static QuartzTaskManager getInstance(){
            return taskManager;
        }
    
    
        /**
         * 添加定时任务
         *
         * @param timingModel 任务model
         * @author YuanXiaohan
         * @date 2021/12/16 3:09 下午
         */
        public void addTask(TimingModel timingModel) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, SchedulerException {
            checkTimingInit();
            // 构建任务信息
            JobDetail jobDetail = JobBuilder.newJob(timingModel.getTaskClass().getDeclaredConstructor().newInstance().getClass())
                    .withDescription(timingModel.getDescription())
                    .withIdentity(timingModel.getTaskName(), timingModel.getGroupName())
                    .build();
    
            // 构建触发器
            Trigger trigger = triggerManager.build(timingModel);
            // 将任务参数放入触发器中
            if (timingModel.getParam() != null && !timingModel.getParam().isEmpty()) {
                trigger.getJobDataMap().putAll(timingModel.getParam());
            }
            // 启动任务
            scheduler.scheduleJob(jobDetail, trigger);
        }
    
        /**
         * 更新任务,任务的标示(由taskName和groupName组成)不变,任务的触发器(触发频率)发生变化
         *
         * @param timingModel 任务model
         * @author YuanXiaohan
         * @date 2021/12/16 3:15 下午
         */
        public void updateTask(TimingModel timingModel) throws SchedulerException {
            // 获取到任务
            TriggerKey triggerKey = TriggerKey.triggerKey(timingModel.getTaskName(), timingModel.getGroupName());
    
            // 构建触发器
            Trigger trigger = triggerManager.build(timingModel);
            // 将任务参数放入触发器中
            if (timingModel.getParam() != null && !timingModel.getParam().isEmpty()) {
                trigger.getJobDataMap().putAll(timingModel.getParam());
            }
            // 将新的触发器绑定到任务标示上重新执行
            scheduler.rescheduleJob(triggerKey, trigger);
        }
    
        /**
         * 更新任务参数
         *
         * @param taskName  任务名
         * @param groupName 任务组名
         * @param param     参数
         * @author YuanXiaohan
         * @date 2021/12/16 3:20 下午
         */
        public void updateTask(String taskName, String groupName, Map<String, Object> param) throws SchedulerException {
            // 获取到任务
            TriggerKey triggerKey = TriggerKey.triggerKey(taskName, groupName);
            Trigger trigger = scheduler.getTrigger(triggerKey);
    
            //修改参数
            trigger.getJobDataMap().putAll(param);
    
            // 将新的触发器绑定到任务标示上重新执行
            scheduler.rescheduleJob(triggerKey, trigger);
        }
    
        /**
         * 删除任务
         *
         * @param taskName  任务名
         * @param groupName 任务组
         * @author YuanXiaohan
         * @date 2021/12/16 3:23 下午
         */
        public void deleteTask(String taskName, String groupName) throws SchedulerException {
            // 暂停任务对应的触发器
            scheduler.pauseTrigger(TriggerKey.triggerKey(taskName, groupName));
            // 删除任务对应的触发器
            scheduler.unscheduleJob(TriggerKey.triggerKey(taskName, groupName));
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(taskName, groupName));
        }
    
        /**
         * 暂停任务
         *
         * @param taskName  添加任务时timingMode中的taskName
         * @param groupName 添加任务时timingMode中的groupName
         * @author YuanXiaohan
         * @date 2021/12/16 3:11 下午
         */
        public void pauseTask(String taskName, String groupName) throws SchedulerException {
            scheduler.pauseJob(JobKey.jobKey(taskName, groupName));
        }
    
    
        /**
         * 将暂停的任务恢复执行
         *
         * @param taskName  添加任务时timingMode中的taskName
         * @param groupName 添加任务时timingMode中的groupName
         * @author YuanXiaohan
         * @date 2021/12/16 3:13 下午
         */
        public void resumeTask(String taskName, String groupName) throws SchedulerException {
            scheduler.resumeJob(JobKey.jobKey(taskName, groupName));
        }
    
        /**
         * 启动所有任务
         *
         * @author YuanXiaohan
         * @date 2021/12/16 3:25 下午
         */
        public void startAllTasks() {
            try {
                scheduler.start();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 关闭定时任务,回收所有的触发器资源
         *
         * @author YuanXiaohan
         * @date 2021/12/16 3:26 下午
         */
        public void shutdownAllTasks() {
            try {
                if (!scheduler.isShutdown()) {
                    scheduler.shutdown();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    
        /**
         * 获取所有的任务,暂时无法获取到任务执行类和任务描述
         *
         * @return java.util.List<org.demo.quartz.mode.TimingModel>
         * @author YuanXiaohan
         * @date 2021/12/16 3:37 下午
         */
        public List<TimingModel> getTaskList() throws SchedulerException {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            List<TimingModel> taskList = new ArrayList<>();
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    TimingModel timingModel;
                    if (trigger instanceof CronTrigger) {
                        timingModel = new CronTimingModel(null, jobKey.getName(), jobKey.getGroup(), null, ((CronTrigger) trigger).getCronExpression());
                        timingModel.setTaskStatus(scheduler.getTriggerState(trigger.getKey()).name());
                        taskList.add(timingModel);
                    } else {
                        log.warn("name:{},group:{}的定时任务类型未知,请拓展QuartzTaskManager.getTaskList的任务类型解析", jobKey.getName(), jobKey.getGroup());
                    }
                }
            }
            return taskList;
        }
    
    
        /**
         * 校验定时调度器是否初始化完成
         *
         * @author YuanXiaohan
         * @date 2021/12/16 2:28 下午
         */
        private void checkTimingInit() {
            if (!initStatus) {
                throw new TimingException("定时器未初始化,添加定时器失败!");
            }
        }
    
    
    }
    
    

    4. Quartz注入到SpringBoot

    package org.demo.quartz.config;
    
    import org.quartz.spi.TriggerFiredBundle;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.scheduling.quartz.AdaptableJobFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * @author Xiaohan.Yuan
     * @version 1.0.0
     * @ClassName TaskJobFactory.java
     * @Description 将Quartz注入springboot
     * @createTime 2021年12月16日
     */
    
    @Component
    public class TaskJobFactory extends AdaptableJobFactory {
        private final AutowireCapableBeanFactory capableBeanFactory;
    
        public TaskJobFactory(AutowireCapableBeanFactory capableBeanFactory) {
            this.capableBeanFactory = capableBeanFactory;
        }
    
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            //调用父类的方法
            Object jobInstance = super.createJobInstance(bundle);
            //进行注入
            capableBeanFactory.autowireBean(jobInstance);
            return jobInstance;
        }
    }
    
    

    5. 执行

    package org.demo;
    
    import org.demo.quartz.QuartzTaskManager;
    import org.demo.quartz.mode.CronTimingModel;
    import org.demo.quartz.mode.IntervalTimingMode;
    import org.demo.quartz.mode.TriggerType;
    import org.demo.quartz.task.TestQuartz;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import java.util.HashMap;
    
    @SpringBootApplication
    public class QuartzApplication implements CommandLineRunner {
    
        public static void main(String[] args) {
            SpringApplication.run(QuartzApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            //构建CRON定时
            //CronTimingModel cronTimingModel = new CronTimingModel(TestQuartz.class, "测试名", "测试组", "测试描述", "*/1 * * * * ?");
            // 构建固定间隔定时
            IntervalTimingMode intervalTimingMode = new IntervalTimingMode(TestQuartz.class, "测试名", "测试组", "测试描述", TriggerType.INTERVAL_SECOND, 5L,null);
            HashMap<String, Object> param = new HashMap<>();
            param.put("paramKey","获取到参数了");
            intervalTimingMode.setParam(param);
            QuartzTaskManager.getInstance().addTask(intervalTimingMode);
        }
    }
    

    5.1 执行结果

      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::                (v2.6.1)
    
    2021-12-16 18:46:55.763  INFO 46460 --- [           main] org.demo.QuartzApplication               : Starting QuartzApplication using Java 11.0.11 on xiaohandeiMac.local with PID 46460 (/Users/xiaohan/IdeaProjects/demo-quartz/target/classes started by xiaohan in /Users/xiaohan/IdeaProjects/demo-quartz)
    2021-12-16 18:46:55.764  INFO 46460 --- [           main] org.demo.QuartzApplication               : No active profile set, falling back to default profiles: default
    2021-12-16 18:46:56.089  INFO 46460 --- [           main] org.quartz.impl.StdSchedulerFactory      : Using default implementation for ThreadExecutor
    2021-12-16 18:46:56.095  INFO 46460 --- [           main] org.quartz.core.SchedulerSignalerImpl    : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    2021-12-16 18:46:56.095  INFO 46460 --- [           main] org.quartz.core.QuartzScheduler          : Quartz Scheduler v.2.3.2 created.
    2021-12-16 18:46:56.096  INFO 46460 --- [           main] org.quartz.simpl.RAMJobStore             : RAMJobStore initialized.
    2021-12-16 18:46:56.096  INFO 46460 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'quartzScheduler' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
      NOT STARTED.
      Currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
    
    2021-12-16 18:46:56.096  INFO 46460 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'quartzScheduler' initialized from an externally provided properties instance.
    2021-12-16 18:46:56.096  INFO 46460 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.3.2
    2021-12-16 18:46:56.096  INFO 46460 --- [           main] org.quartz.core.QuartzScheduler          : JobFactory set to: org.springframework.scheduling.quartz.SpringBeanJobFactory@2d6aca33
    2021-12-16 18:46:56.099  INFO 46460 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED started.
    2021-12-16 18:46:56.147  INFO 46460 --- [           main] org.demo.QuartzApplication               : Started QuartzApplication in 0.589 seconds (JVM running for 6.058)
    1
    2021-12-16 18:46:56.156  INFO 46460 --- [eduler_Worker-1] org.demo.quartz.task.TestQuartz          : ----------------------
    任务组:测试名
    任务名:测试组
    任务描述:测试描述
    获取参数paramKey:获取到参数了
    ----------------------
    2
    2021-12-16 18:47:01.155  INFO 46460 --- [eduler_Worker-2] org.demo.quartz.task.TestQuartz          : ----------------------
    任务组:测试名
    任务名:测试组
    任务描述:测试描述
    获取参数paramKey:获取到参数了
    ----------------------
    3
    2021-12-16 18:47:06.151  INFO 46460 --- [eduler_Worker-3] org.demo.quartz.task.TestQuartz          : ----------------------
    任务组:测试名
    任务名:测试组
    任务描述:测试描述
    获取参数paramKey:获取到参数了
    ----------------------
    

    源码

    Gitee

    展开全文
  • Springboot集成quartz

    2021-11-04 14:20:41
    #该依赖有spring对quartz的支持 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency>...

    1.添加依赖

    #该依赖有spring对quartz的支持
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
    <dependency> 
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
    </dependency>
    <dependency> 
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz-jobs</artifactId>
        <version>2.2.1</version>
    </dependency>
    

    2.实现思路
    参考https://blog.csdn.net/lkl_csdn/article/details/73613033
    https://www.jianshu.com/p/e95d6764b4d9

    自定义注解标注在定时任务类和定时方法上
    定义实体类,包含类名、方法名,状态等属性
    定义一个扫描类,实现ApplicationContextAware接口和InitializingBean,获取到ApplicationContext对象,利用ApplicationContext对象获取到所有标注了自定义注解的类,然后拿到所有标注了自定义注解的方法,将属性插入到数据库。覆盖afterPropertiesSet方法,在该方法中调用上述方法。
    定义工具类ApplicationContextUtil,利用ApplicationContextUtil根据全类名获取具体的对象。再拿到对象下所有标注了自定义注解的方法,执行该方法
    定义监听器类实现ApplicationListener接口,去数据库查询所有定时任务,如果状态为null,则设为running,并修改数据库数据,把它添加到Scheduler。如果状态为not running ,则暂停该任务,最后调用start方法启动Scheduler。
    实现job接口,覆盖execute方法,调用上述工具类方法
    定义Controller和Service,在service中注入SchedulerFactoryBean,想直接引用SchedulerFactoryBean,要先把它注入到ioc容器中,使用@component注解+bean注解注入SchedulerFactoryBean。利用SchedulerFactoryBean来获取Scheduler,并且用Scheduler定义一个start方法。提供动态调度定时任务的接口。

    展开全文
  • SpringBoot集成Quartz

    2021-07-16 23:55:01
    目的:订单 --》Quartz / 延迟队列 / 前端定时器 1、订单未支付倒计时取消 (支付超时) 2、支付之后收获的待确认 (自动确认) ---- 收了货不确认,平台就不会把钱打给 总共4类型订单 1、领养 2、服务 3、...
  • SpringBoot集成Quartz框架

    千次阅读 2021-12-24 15:28:35
    SpringBoot集成Quartz框架 (一)集成环境: ​ Win10系统 ​ JDK版本:11.0.13 ​ SpringBoot版本:2.3.4。RELEASE ​ Quartz版本:2.3.2 (二)代码实现 前期准备: 1.创建一个空项目springboot-demo 2....
  • SpringBoot 集成 Quartz 实现可控的任务 建立数据库,运行脚本,数据库sql脚本位于 quartz\src\main\resources\schema\schema-mysql.sql。 修改Spring boot配置文件相应的数据库连接参数。 运行Spring-Boot项目。 ...
  • 今天小编就为大家分享一篇关于SpringBootQuartz集成实现分布式定时任务集群的代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • SpringBoot集成Quartz(定时任务)

    千次阅读 2022-01-24 21:44:44
    quartz是OpenSymphony开源组织在Job scheduling领域的开源项目,是由java开发的一个开源的任务日程管理系统。 quartz能做什么? 作业调度:调用各种框架的作业脚本,例如shell,hive等。 定时任务:在某一预定的时刻...
  • springboot集成quartz,简版-通俗易懂

    千次阅读 2020-11-06 14:21:10
    文章导航springboot使用quartz执行任务添加POM依赖1. 任务调度器2. 启动项目时将quartz也启动3. 需要执行的业务任务cron表达式生成工具类测试代码 springboot使用quartz执行任务 添加POM依赖 <dependency> &...
  • Spring Boot 整合 Quartz 实现定时任务集群 文章参考 https://blog.csdn.net/l18848956739/article/details/86597709 https://blog.csdn.net/xibei19921101/article/details/105012749 ...
  • 一、Quartz 简介 Quartz 是 OpenSymphony 开源组织在 Job Scheduling 领域又一个开源项目,是完全由 Java 开发的一个开源任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责...
  • SpringBoot集成quartz实现动态定时任务 (1)Quartz简介 Quartz三大组件: 一、调度器scheduler 二、任务job 三、触发器tigger 1、job:job是一个接口,通过实现job接口,可实现需要定时执行的代码逻辑。 2、...
  • 定时任务功能
  • 一,quartz介绍 1,调度器:scheduler 任务调度的控制器,负责定时任务的调度,并提供任务和触发器的增删改查等api方法。 2,任务:job job是实际被调度的任务,每个任务必须指定具体执行任务的实现类,实现类需要...
  • Quartz是一个定时任务框架,其他介绍网上也很详尽。这里要介绍一下Quartz里的几个非常核心的接口。通过实例代码给大家讲解SpringBoot集成Quartz实现定时任务的方法,感兴趣的朋友一起看看吧
  • 步骤 1.定时刷新数据库表中数据,如果是新增的数据则创建新的任务,如果只是针对时间修改的任务,则刷新改任务的时间 2.网络上的很多都是一个任务,没谈论到多个任务的案例 ------------------------------------...
  • 本篇文章主要介绍了springboot整合Quartz实现动态配置定时任务的方法,非常具有实用价值,需要的朋友可以参考下
  • spring-cloud-alibaba+dubbo+nacos+quartz以yml配置方式实现
  • 分布式部署的微服务架构,springboot自带的定时器无法满足我们的场景,这时候我们需要集成一套支持分布式调度的框架来解决。 首先我们去quartz官网下载 下载地址:[添加链接描述]...
  • springboot集成quartz2.3.0

    2021-03-13 19:36:14
    序quartz是java里头定时任务的经典开源实现,这里讲述一下如何在springboot集成quartz。mavenorg.springframeworkspring-txorg.springframeworkspring-context-supportorg.quartz-schedulerquartz${quartz.version...
  • 1、什么是Quartz quartz是一个功能丰富的开源的任务调用系统,它可以定义很多job并发执行,支持事务和集群 2、可以做什么 定义任务,在任何时刻,或者某一时刻可以做想执行的任务 3、Quartz 三要素: Scheduler:...
  • 这两天在纠结一个问题,以前的项目由SSM转为...今天在stackflow上看到一篇文章解决了我的问题,因为springboot项目中引用了devtools,而阻止了quartz对bean的实例创建而导致,依赖中删除devtools的引用,问题解决。 ...
  • 本文主要是Springboot集成Quartz实现定时任务的数据库存储以及前端页面的可视化管理,所使用的主要工具有:Springboot、Mybatis-Plus、Quartz、Layui、Mysql等 正文 1.准备环境 1.创建数据库 因为本例子中业务数据和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,535
精华内容 2,214
关键字:

springboot集成quartz

spring 订阅