Pārlūkot izejas kodu

初始化 Quartz 的整体代码

YunaiV 4 gadi atpakaļ
vecāks
revīzija
dadb66c8e9

+ 180 - 170
sql/quartz.sql

@@ -1,170 +1,180 @@
--- ----------------------------
--- 1、存储每一个已配置的 jobDetail 的详细信息
--- ----------------------------
-drop table if exists QRTZ_JOB_DETAILS;
-create table QRTZ_JOB_DETAILS (
-    sched_name           varchar(120)    not null,
-    job_name             varchar(200)    not null,
-    job_group            varchar(200)    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;
-
--- ----------------------------
--- 2、 存储已配置的 Trigger 的信息
--- ----------------------------
-drop table if exists QRTZ_TRIGGERS;
-create table QRTZ_TRIGGERS (
-    sched_name           varchar(120)    not null,
-    trigger_name         varchar(200)    not null,
-    trigger_group        varchar(200)    not null,
-    job_name             varchar(200)    not null,
-    job_group            varchar(200)    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(200)    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;
-
--- ----------------------------
--- 3、 存储简单的 Trigger,包括重复次数,间隔,以及已触发的次数
--- ----------------------------
-drop table if exists QRTZ_SIMPLE_TRIGGERS;
-create table QRTZ_SIMPLE_TRIGGERS (
-    sched_name           varchar(120)    not null,
-    trigger_name         varchar(200)    not null,
-    trigger_group        varchar(200)    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;
-
--- ----------------------------
--- 4、 存储 Cron Trigger,包括 Cron 表达式和时区信息
--- ---------------------------- 
-drop table if exists QRTZ_CRON_TRIGGERS;
-create table QRTZ_CRON_TRIGGERS (
-    sched_name           varchar(120)    not null,
-    trigger_name         varchar(200)    not null,
-    trigger_group        varchar(200)    not null,
-    cron_expression      varchar(200)    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;
-
--- ----------------------------
--- 5、 Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)
--- ---------------------------- 
-drop table if exists QRTZ_BLOB_TRIGGERS;
-create table QRTZ_BLOB_TRIGGERS (
-    sched_name           varchar(120)    not null,
-    trigger_name         varchar(200)    not null,
-    trigger_group        varchar(200)    not null,
-    blob_data            blob            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;
-
--- ----------------------------
--- 6、 以 Blob 类型存储存放日历信息, quartz可配置一个日历来指定一个时间范围
--- ---------------------------- 
-drop table if exists QRTZ_CALENDARS;
-create table QRTZ_CALENDARS (
-    sched_name           varchar(120)    not null,
-    calendar_name        varchar(200)    not null,
-    calendar             blob            not null,
-    primary key (sched_name,calendar_name)
-) engine=innodb;
-
--- ----------------------------
--- 7、 存储已暂停的 Trigger 组的信息
--- ---------------------------- 
-drop table if exists QRTZ_PAUSED_TRIGGER_GRPS;
-create table QRTZ_PAUSED_TRIGGER_GRPS (
-    sched_name           varchar(120)    not null,
-    trigger_group        varchar(200)    not null,
-    primary key (sched_name,trigger_group)
-) engine=innodb;
-
--- ----------------------------
--- 8、 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息
--- ---------------------------- 
-drop table if exists QRTZ_FIRED_TRIGGERS;
-create table QRTZ_FIRED_TRIGGERS (
-    sched_name           varchar(120)    not null,
-    entry_id             varchar(95)     not null,
-    trigger_name         varchar(200)    not null,
-    trigger_group        varchar(200)    not null,
-    instance_name        varchar(200)    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(200)    null,
-    job_group            varchar(200)    null,
-    is_nonconcurrent     varchar(1)      null,
-    requests_recovery    varchar(1)      null,
-    primary key (sched_name,entry_id)
-) engine=innodb;
-
--- ----------------------------
--- 9、 存储少量的有关 Scheduler 的状态信息,假如是用于集群中,可以看到其他的 Scheduler 实例
--- ---------------------------- 
-drop table if exists QRTZ_SCHEDULER_STATE; 
-create table QRTZ_SCHEDULER_STATE (
-    sched_name           varchar(120)    not null,
-    instance_name        varchar(200)    not null,
-    last_checkin_time    bigint(13)      not null,
-    checkin_interval     bigint(13)      not null,
-    primary key (sched_name,instance_name)
-) engine=innodb;
-
--- ----------------------------
--- 10、 存储程序的悲观锁的信息(假如使用了悲观锁)
--- ---------------------------- 
-drop table if exists QRTZ_LOCKS;
-create table QRTZ_LOCKS (
-    sched_name           varchar(120)    not null,
-    lock_name            varchar(40)     not null,
-    primary key (sched_name,lock_name)
-) engine=innodb;
-
-drop table if exists QRTZ_SIMPROP_TRIGGERS;
-create table QRTZ_SIMPROP_TRIGGERS (
-    sched_name           varchar(120)    not null,
-    trigger_name         varchar(200)    not null,
-    trigger_group        varchar(200)    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;
-
-commit;
+
+#
+# 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;

+ 12 - 0
src/main/java/cn/iocoder/dashboard/framework/quartz/core/enums/JobDataKeyEnum.java

@@ -0,0 +1,12 @@
+package cn.iocoder.dashboard.framework.quartz.core.enums;
+
+/**
+ * Quartz Job Data 的 key 枚举
+ */
+public enum JobDataKeyEnum {
+
+    JOB_ID,
+    JOB_HANDLER_NAME,
+    JOB_HANDLER_PARAM
+
+}

+ 21 - 0
src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandler.java

@@ -0,0 +1,21 @@
+package cn.iocoder.dashboard.framework.quartz.core.handler;
+
+import cn.iocoder.dashboard.common.pojo.CommonResult;
+
+/**
+ * 任务处理器
+ *
+ * @author 芋道源码
+ */
+public interface JobHandler {
+
+    /**
+     * 执行任务
+     *
+     * @param param 参数
+     * @return 结果
+     * @throws Exception 异常
+     */
+    CommonResult<String> execute(String param) throws Exception;
+
+}

+ 49 - 0
src/main/java/cn/iocoder/dashboard/framework/quartz/core/handler/JobHandlerInvoker.java

@@ -0,0 +1,49 @@
+package cn.iocoder.dashboard.framework.quartz.core.handler;
+
+import cn.iocoder.dashboard.framework.quartz.core.enums.JobDataKeyEnum;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.JobExecutionContext;
+import org.quartz.PersistJobDataAfterExecution;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import javax.annotation.Resource;
+
+/**
+ * 基础 Job 调用者,负责调用 {@link JobHandler#execute(String)} 执行任务
+ *
+ * @author 芋道源码
+ */
+@PersistJobDataAfterExecution
+@DisallowConcurrentExecution
+public class JobHandlerInvoker extends QuartzJobBean {
+
+    @Resource
+    private ApplicationContext applicationContext;
+
+    @Override
+    protected void executeInternal(JobExecutionContext executionContext) {
+        // 获得 JobHandler 对象
+        String jobHandlerName = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_NAME);
+        JobHandler jobHandler = applicationContext.getBean(jobHandlerName, JobHandler.class);
+
+        // 执行任务
+        String jobParam = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_PARAM);
+        try {
+            jobHandler.execute(jobParam);
+        } catch (Exception e) {
+            // TODO 需要后续处理
+        }
+    }
+
+    @SuppressWarnings("SwitchStatementWithTooFewBranches")
+    private static String getJobData(JobExecutionContext executionContext, JobDataKeyEnum key) {
+        switch (key) {
+            case JOB_ID:
+                return executionContext.getJobDetail().getJobDataMap().getString(key.name());
+            default:
+                return executionContext.getTrigger().getJobDataMap().getString(key.name());
+        }
+    }
+
+}

+ 75 - 0
src/main/java/cn/iocoder/dashboard/framework/quartz/core/scheduler/SchedulerManager.java

@@ -0,0 +1,75 @@
+package cn.iocoder.dashboard.framework.quartz.core.scheduler;
+
+import cn.iocoder.dashboard.framework.quartz.core.enums.JobDataKeyEnum;
+import cn.iocoder.dashboard.framework.quartz.core.handler.JobHandlerInvoker;
+import org.quartz.*;
+
+/**
+ * {@link org.quartz.Scheduler} 的管理器,负责创建任务
+ *
+ * @author 芋道源码
+ */
+public class SchedulerManager {
+
+    private final Scheduler scheduler;
+
+    public SchedulerManager(Scheduler scheduler) {
+        this.scheduler = scheduler;
+    }
+
+    public void addJob(Long jobId, String jobHandlerName, String jobHandlerParam,
+                       String triggerName, String cronExpression)
+            throws SchedulerException {
+        // 创建 JobDetail 对象
+        JobDetail jobDetail = JobBuilder.newJob(JobHandlerInvoker.class)
+                .usingJobData(JobDataKeyEnum.JOB_ID.name(), jobId)
+                .withIdentity(jobHandlerName).build();
+        // 创建 Trigger 对象
+        Trigger trigger = TriggerBuilder.newTrigger()
+                .withIdentity(triggerName)
+                .usingJobData(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName)
+                .usingJobData(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam)
+                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
+                .build();
+        // 新增调度
+        scheduler.scheduleJob(jobDetail, trigger);
+    }
+
+    public void updateJob(String jobHandlerName, String jobHandlerParam,
+                          String triggerName, String cronExpression) throws SchedulerException {
+        // 创建 Trigger 对象
+        Trigger trigger = TriggerBuilder.newTrigger()
+                .withIdentity(triggerName)
+                .usingJobData(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName)
+                .usingJobData(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam)
+                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
+                .build();
+        // 修改调度
+        scheduler.rescheduleJob(new TriggerKey(triggerName), trigger);
+    }
+
+    public void deleteJob(String jobHandlerName) throws SchedulerException {
+        scheduler.deleteJob(new JobKey(jobHandlerName));
+    }
+
+    public void pauseJob(String jobHandlerName) throws SchedulerException {
+        scheduler.pauseJob(new JobKey(jobHandlerName));
+    }
+
+    public void resumeJob(String jobHandlerName,
+                          String triggerName) throws SchedulerException {
+        scheduler.resumeJob(new JobKey(jobHandlerName));
+        scheduler.resumeTrigger(new TriggerKey(triggerName));
+    }
+
+    public void triggerJob(Long jobId, String jobHandlerName, String jobHandlerParam)
+            throws SchedulerException {
+        JobDataMap data = new JobDataMap();
+        data.put(JobDataKeyEnum.JOB_ID.name(), jobId);
+        data.put(JobDataKeyEnum.JOB_HANDLER_NAME.name(), jobHandlerName);
+        data.put(JobDataKeyEnum.JOB_HANDLER_PARAM.name(), jobHandlerParam);
+        // 触发任务
+        scheduler.triggerJob(new JobKey(jobHandlerName), data);
+    }
+
+}

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJob.java → src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobDO.java

@@ -12,7 +12,7 @@ import lombok.ToString;
 import java.util.Date;
 
 /**
- * 定时任务
+ * 定时任务 DO
  *
  * @author 芋道源码
  */
@@ -20,7 +20,7 @@ import java.util.Date;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class InfJob extends BaseDO {
+public class InfJobDO extends BaseDO {
 
     /**
      * 任务编号

+ 7 - 7
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLog.java → src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/job/InfJobLogDO.java

@@ -18,7 +18,7 @@ import java.util.Date;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class InfJobLog extends BaseDO {
+public class InfJobLogDO extends BaseDO {
 
     /**
      * 日志编号
@@ -27,31 +27,31 @@ public class InfJobLog extends BaseDO {
     /**
      * 任务编号
      *
-     * 关联 {@link InfJob#getId()}
+     * 关联 {@link InfJobDO#getId()}
      */
     private Long jobId;
     /**
      * 任务名称
      *
-     * 冗余字段 {@link InfJob#getName()}
+     * 冗余字段 {@link InfJobDO#getName()}
      */
     private String jobName;
     /**
      * 任务分组
      *
-     * 冗余字段 {@link InfJob#getGroup()}
+     * 冗余字段 {@link InfJobDO#getGroup()}
      */
     private String jobGroup;
     /**
      * 处理器的名字
      *
-     * 冗余字段 {@link InfJob#getHandlerName()}
+     * 冗余字段 {@link InfJobDO#getHandlerName()}
      */
     private String handlerName;
     /**
      * 处理器的参数
      *
-     * 冗余字段 {@link InfJob#getHandlerParam()}
+     * 冗余字段 {@link InfJobDO#getHandlerParam()}
      */
     private String handlerParam;
 
@@ -82,7 +82,7 @@ public class InfJobLog extends BaseDO {
     /**
      * 结果数据
      *
-     * 如果是对象,则使用 JSON 格式化
+     * 目前使用的 {@link CommonResult#getData()} 数据
      */
     private String resultData;
 

+ 29 - 0
src/main/resources/application.yaml

@@ -42,6 +42,35 @@ spring:
 #  main:
 #    lazy-initialization: true # TODO 芋艿:本地开发环境,可以配置下 lazy 延迟加载
 
+  # Quartz 配置项,对应 QuartzProperties 配置类
+  quartz:
+    scheduler-name: clusteredScheduler # Scheduler 名字。默认为 schedulerName
+    job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
+    auto-startup: true # Quartz 是否自动启动
+    startup-delay: 0 # 延迟 N 秒启动
+    wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
+    overwrite-existing-jobs: false # 是否覆盖已有 Job 的配置
+    properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档
+      org:
+        quartz:
+          # JobStore 相关配置
+          jobStore:
+            # 数据源名称
+#            dataSource: quartzDataSource # 使用的数据源 TODO 使用默认数据源
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX # JobStore 实现类
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+            tablePrefix: QRTZ_ # Quartz 表前缀
+            isClustered: true # 是集群模式
+            clusterCheckinInterval: 1000
+            useProperties: false
+          # 线程池相关配置
+          threadPool:
+            threadCount: 25 # 线程池大小。默认为 10 。
+            threadPriority: 5 # 线程优先级
+            class: org.quartz.simpl.SimpleThreadPool # 线程池类型
+    jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置
+      initialize-schema: never # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
+
 # 芋道配置项,设置当前项目所有自定义的配置
 yudao:
   info: