• 基于springboot创建的web项目整合Quartz框架


    介绍

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或EJBs。Quartz的最新版本为Quartz 2.3.2。

    • quartz可以在某一个有规律的时间点干某件事,是一个任务调度框架,可以被集成到java的各种应用中使用,quartz框架可以支持分布式任务处理

    基于springboot创建的web项目整合Quartz框架

    • 整体代码结构
      在这里插入图片描述

    • 导入依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 创建quartz_demo数据库,执行tables_mysql_innodb.sql文件创建对应表,下面是文件内容
    #
    # In your Quartz properties file, you'll need to set
    # org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    #
    #
    # By: Ron Cordell - roncordell
    #  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.
    
    DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
    DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
    DROP TABLE IF EXISTS QRTZ_LOCKS;
    DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_TRIGGERS;
    DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
    DROP TABLE IF EXISTS QRTZ_CALENDARS;
    
    CREATE TABLE QRTZ_JOB_DETAILS(
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME VARCHAR(190) NOT NULL,
    JOB_GROUP VARCHAR(190) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    JOB_NAME VARCHAR(190) NOT NULL,
    JOB_GROUP VARCHAR(190) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(190) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
    REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_CRON_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    CRON_EXPRESSION VARCHAR(120) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_SIMPROP_TRIGGERS
      (
        SCHED_NAME VARCHAR(120) NOT NULL,
        TRIGGER_NAME VARCHAR(190) NOT NULL,
        TRIGGER_GROUP VARCHAR(190) NOT NULL,
        STR_PROP_1 VARCHAR(512) NULL,
        STR_PROP_2 VARCHAR(512) NULL,
        STR_PROP_3 VARCHAR(512) NULL,
        INT_PROP_1 INT NULL,
        INT_PROP_2 INT NULL,
        LONG_PROP_1 BIGINT NULL,
        LONG_PROP_2 BIGINT NULL,
        DEC_PROP_1 NUMERIC(13,4) NULL,
        DEC_PROP_2 NUMERIC(13,4) NULL,
        BOOL_PROP_1 VARCHAR(1) NULL,
        BOOL_PROP_2 VARCHAR(1) NULL,
        PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
        FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_BLOB_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_CALENDARS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME VARCHAR(190) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_FIRED_TRIGGERS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(190) NOT NULL,
    TRIGGER_GROUP VARCHAR(190) NOT NULL,
    INSTANCE_NAME VARCHAR(190) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(190) NULL,
    JOB_GROUP VARCHAR(190) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_SCHEDULER_STATE (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(190) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
    ENGINE=InnoDB;
    
    CREATE TABLE QRTZ_LOCKS (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME VARCHAR(40) NOT NULL,
    PRIMARY KEY (SCHED_NAME,LOCK_NAME))
    ENGINE=InnoDB;
    
    CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
    CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
    
    CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
    CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
    CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
    CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
    CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
    CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
    CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
    CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
    CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
    CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
    CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
    CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
    
    CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
    CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
    CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
    CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
    CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
    CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
    
    commit;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 配置quartz
    server:
      port: ${PORT:12011}
      servlet:
        session:
          timeout: 86400s # session有效期(xxx秒)
          cookie:
            http-only: false # 如果为true, 浏览器脚本将无法访问cookie
            secure: false # 如果为true, 则仅通过https连接发送cookie, http无法携带cookie
        context-path:  # 程序上下文路径配置
    spring:
      application:
        name: quartz-demo
      aop:
        proxy-target-class: true
        auto: true
      datasource:
        url: jdbc:mysql://localhost:3306/quartz_demo
        username: root
        password: 123456
        driver-class-name: com.mysql.jdbc.Driver
      # 配置日期格式化
      jackson:
        date-format: yyyy-MM-dd HH:mm:ss  #时间戳统一转换为指定格式
        time-zone: GMT+8  # 时区修改为东8区
      quartz:
        # 将任务等保存化到数据库
        job-store-type: jdbc
        # 程序结束时会等待quartz相关的内容结束
        wait-for-jobs-to-complete-on-shutdown: true
        # QuartzScheduler启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录
        overwrite-existing-jobs: true
        properties:
          org:
            quartz:
              # scheduler相关
              scheduler:
                # scheduler的实例名
                instanceName: scheduler
                instanceId: AUTO
              # 持久化相关
              jobStore:
                class: org.quartz.impl.jdbcjobstore.JobStoreTX
                driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
                # 表示数据库中相关表是QRTZ_开头的
                tablePrefix: QRTZ_
                useProperties: false
                # 配置集群
                # 是否加入集群
                isClustered: true
                # 容许的最大作业延长时间
                clusterCheckinInterval: 20000
              # 线程池相关
              threadPool:
                class: org.quartz.simpl.SimpleThreadPool
                # 线程数
                threadCount: 10
                # 线程优先级
                threadPriority: 5
                threadsInheritContextClassLoaderOfInitializingThread: true
    mybatis-plus:
      global-config:
        db-config:
          logic-delete-field: is_deleted
          logic-delete-value: 1
          logic-not-delete-value: 0
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    logging:
      level:
        com.my.quartz: debug
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    添加sys_job表

    CREATE TABLE `sys_job` (
      `id` bigint(11) NOT NULL AUTO_INCREMENT,
      `job_id` varchar(100) DEFAULT NULL,
      `job_name` varchar(255) DEFAULT NULL,
      `job_group_name` varchar(255) DEFAULT NULL,
      `invoke_target` varchar(255) NOT NULL,
      `cron_expression` varchar(50) DEFAULT NULL,
      `misfire_policy` varchar(255) DEFAULT NULL COMMENT 'cron计划策略0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行',
      `status` varchar(10) DEFAULT NULL COMMENT '任务状态(0正常 1暂停)',
      `concurrent` varchar(10) DEFAULT NULL COMMENT '是否并发执行(0允许 1禁止)',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    写两条数据
    在这里插入图片描述

    依次实现mvc三层

    • mapper层的xml文件
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.my.quartz.boot.mapper.SysJobMapper">
        <resultMap id="BaseResultMap" type="com.my.quartz.boot.SysJob">
            <id column="id" jdbcType="BIGINT" property="id" />
            <result column="job_id" jdbcType="VARCHAR" property="jobId" />
            <result column="job_name" jdbcType="VARCHAR" property="jobName" />
            <result column="job_group_name" jdbcType="VARCHAR" property="jobGroupName" />
            <result column="invoke_target" jdbcType="VARCHAR" property="invokeTarget" />
            <result column="cron_expression" jdbcType="VARCHAR" property="cronExpression" />
            <result column="misfire_policy" jdbcType="VARCHAR" property="misfirePolicy" />
            <result column="status" jdbcType="VARCHAR" property="status" />
            <result column="concurrent" jdbcType="VARCHAR" property="concurrent" />
        </resultMap>
        <sql id="Base_Column_List">
            t.id, t.job_id jobId, t.job_name jobName, t.job_group_name jobGroupName, t.invoke_target invokeTarget, t.cron_expression cronExpression, t.misfire_policy misfirePolicy, t.status, t.concurrent
        </sql>
    </mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • mapper接口
    /**
     * Auto Generated
     *
     * @author :Boy
     * @date :Created in 2022-06-18
     * @description:
     * @modified By:
     */
    public interface SysJobMapper extends BaseMapper<SysJob> {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • service接口
    public interface SysJobService extends IService<SysJob> {
    
    }
    
    • 1
    • 2
    • 3
    • service接口实现
    @Service
    public class SysJobServiceImpl extends ServiceImpl<SysJobMapper, SysJob> implements SysJobService {
        @Autowired
        private Scheduler scheduler;
        @Autowired
        private ScheduleUtils scheduleUtils;
    
        /**
         * 项目启动时,初始化定时器
         * 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据)
         */
        @PostConstruct
        public void init() throws SchedulerException, TaskException {
            scheduler.clear();
            List<SysJob> jobList = baseMapper.selectList(null);
            for (SysJob job : jobList) {
                scheduleUtils.createScheduleJob(scheduler, job);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • controller代码
    @RestController
    @RequestMapping("/job")
    public class SysJobController {
        @Resource
        private SysJobService sysJobService;
        @Resource
        private ScheduleUtils scheduleUtils;
        @Resource
        private Scheduler scheduler;
    
        @PostMapping("/add")
        public Object add(@RequestBody SysJob entity) throws SchedulerException, TaskException {
            sysJobService.save(entity);
            scheduleUtils.createScheduleJob(scheduler, entity);
            return "ok";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • ScheduleUtils 定时任务工具类
    /**
     * @Author ScholarTang
     * @Date 2021/7/15 下午3:50
     * @Desc 定时任务工具类
     */
    @Component
    public class ScheduleUtils {
    
        @Autowired
        private Scheduler scheduler;
    
        /**
         * 构建任务触发对象
         *
         * @param jobName
         * @param jobGroup
         * @return
         */
        public TriggerKey getTriggerKey(String jobName, String jobGroup) {
            return TriggerKey.triggerKey(jobName, jobGroup);
        }
    
        /**
         * 构建任务键对象
         *
         * @param jobName
         * @param jobGroup
         * @return
         */
        public JobKey getJobKey(String jobName, String jobGroup) {
            return JobKey.jobKey(jobName, jobGroup);
        }
    
        /**
         * 创建定时调度任务
         *
         *
         * @param scheduler
         * @param job
         * @throws SchedulerException
         * @throws TaskException
         */
        public void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException {
            // 构建job信息
            String jobName = job.getJobId() + "_" + job.getJobName();
            String jobGroupName = job.getJobGroupName();
    
            //TODO 反射动态获取Job实现类
            //构建job实例
            JobDetail jobDetail = JobBuilder.newJob(QuartzJobImpl.class)
                    .withIdentity(getJobKey(jobName, jobGroupName))
                    .build();
            jobDetail.getJobDataMap().put("QuartzJobExecutionData", job);
            // 表达式调度构建器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
    
            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobName, jobGroupName))
                    .withSchedule(cronScheduleBuilder).build();
    
            // 放入参数,运行时的方法可以获取
            jobDetail.getJobDataMap().put("QuartzJobExecutionData", job);
    
            // 判断是否存在
            if (scheduler.checkExists(getJobKey(jobName, jobGroupName))) {
                // 防止创建时存在数据问题 先移除,然后在执行创建操作
                scheduler.deleteJob(getJobKey(jobName, jobGroupName));
            }
    
            //创建定时任务调度
            scheduler.scheduleJob(jobDetail, trigger);
    
            // 暂停任务 规定 0启动 1暂停
            if (job.getStatus().equals("1")) {
                scheduler.pauseJob(getJobKey(jobName, jobGroupName));
            }
        }
    
    
        /**
         * 删除定时调度任务
         *
         * @param sysJob
         * @throws SchedulerException
         */
        public void deleteScheduleJob(SysJob sysJob) throws SchedulerException {
            scheduler.deleteJob(getJobKey(sysJob.getJobId() + "_" + sysJob.getJobName(), sysJob.getJobGroupName()));
        }
    
    
        /**
         * 设置定时任务策略
         *
         * @param sysJob
         * @param cronScheduleBuilder
         * @return
         */
        public CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob sysJob, CronScheduleBuilder cronScheduleBuilder) throws TaskException {
            switch (sysJob.getMisfirePolicy()) {
                case "0":
                    return cronScheduleBuilder;
                case "1":
                    return cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires();
                case "2":
                    return cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed();
                case "3":
                    return cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();
                default:
                    throw new TaskException("任务失败策略 '" + sysJob.getMisfirePolicy()
                            + "' 不能在cron计划任务中使用", TaskException.Code.CONFIG_ERROR);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 创建一个Job实现类,只是一个简单实现类,没有对方法添加参数
    @Slf4j
    @Component
    public class QuartzJobImpl implements Job {
    
        @Autowired
        private ApplicationContext context;
    
        @SneakyThrows
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            SysJob sysJob = new SysJob();
            BeanUtils.copyProperties(jobExecutionContext.getMergedJobDataMap().get("QuartzJobExecutionData"), sysJob);
            log.info("正在执行任务");
            String invokeTarget = sysJob.getInvokeTarget();
            String beanName = invokeTarget.split("\\.")[0];
            String methodName = invokeTarget.split("\\.")[1];
            Object bean = context.getBean(beanName);
            Class<?> clazz = bean.getClass();
            Method method = clazz.getMethod(methodName);
            method.invoke(bean);
            log.info("已结束任务");
            System.out.println();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 创建最终任务执行类,执行函数级别的定时任务,数据库中的invoke_target是和这里放入spring中的名称相同的,quartz_target.hello最终执行的函数就是hello函数
    @Slf4j
    @Component("quartz_target")
    public class QuartzJobExe {
    
        @Resource
        private Scheduler scheduler;
    
        public void hello() throws Exception {
            System.out.println("[job]实例执行...hello..." + System.currentTimeMillis());
        }
    
        public void action() throws Exception {
            System.out.println("[job]实例执行...action..." + System.currentTimeMillis());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 最终代码结构
      在这里插入图片描述

    • 启动spring boot之后的任务状态
      在这里插入图片描述

    • 使用postman工具类添加一个任务
      在这里插入图片描述

    • 然后在代码中添加一个对应的方法
      在这里插入图片描述

    • 重新启动springboot的运行结果
      在这里插入图片描述

    理论上使用这样的反射方式可以运行任何代码的

  • 相关阅读:
    软件定义存储不能打?这家成立刚三年的公司问鼎全球存储性能榜
    You may use special comments to disable some warnings
    Jmeter分布式部署执行和常见报错
    【20221206】【每日一题】01背包的基础
    Unity webgl 关于适配网页 ,并且用到js中的SetTimeOut和SetInterval()
    DM8实时主备与读写分离的区别
    淘宝API详情接口调用示例
    详解JS——垃圾回收的原理
    会话管理(Cookie和Session)知识点总结-DX的笔记
    PHP 语法...的用法
  • 原文地址:https://blog.csdn.net/qq_27577113/article/details/125356422