SpringBoot整合Quartz实现动态任务调度

1、主要依赖

<!-- 定时任务 -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!--常用工具类 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

<!--Spring框架基本的核心工具-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.2.0</version>
</dependency>

<!-- Mysql驱动包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

2、全局配置文件

配置数据库连接和mybatis-plus。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/quartz?serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456

mybatis-plus:
  #要扫描的xml路径
  mapper-locations: classpath:mapping/*.xml
  #要扫描的包路径
  type-aliases-package: com.quartz.domain
  configuration:
    #开启驼峰命名
    map-underscore-to-camel-case: true
    #关缓存
    cache-enabled: false

3、Quartz数据库结构

共计12张表,只有最后一张表需要使用者自己创建,其他以qrtz开头的表使用者不必操作。

/*
Navicat MySQL Data Transfer

Source Server         : root
Source Server Version : 80018
Source Host           : localhost:3306
Source Database       : quartz

Target Server Type    : MYSQL
Target Server Version : 80018
File Encoding         : 65001

Date: 2020-04-23 17:47:42
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for qrtz_blob_triggers
-- ----------------------------
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,
  PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
  CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_calendars
-- ----------------------------
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 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_cron_triggers
-- ----------------------------
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) DEFAULT NULL,
  PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
  CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_fired_triggers
-- ----------------------------
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` int(11) NOT NULL,
  `state` varchar(16) NOT NULL,
  `job_name` varchar(200) DEFAULT NULL,
  `job_group` varchar(200) DEFAULT NULL,
  `is_nonconcurrent` varchar(1) DEFAULT NULL,
  `requests_recovery` varchar(1) DEFAULT NULL,
  PRIMARY KEY (`sched_name`,`entry_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_job_details
-- ----------------------------
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) DEFAULT 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,
  PRIMARY KEY (`sched_name`,`job_name`,`job_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_locks
-- ----------------------------
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 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_paused_trigger_grps
-- ----------------------------
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 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_scheduler_state
-- ----------------------------
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 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_simple_triggers
-- ----------------------------
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`),
  CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_simprop_triggers
-- ----------------------------
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) DEFAULT NULL,
  `str_prop_2` varchar(512) DEFAULT NULL,
  `str_prop_3` varchar(512) DEFAULT NULL,
  `int_prop_1` int(11) DEFAULT NULL,
  `int_prop_2` int(11) DEFAULT NULL,
  `long_prop_1` bigint(20) DEFAULT NULL,
  `long_prop_2` bigint(20) DEFAULT NULL,
  `dec_prop_1` decimal(13,4) DEFAULT NULL,
  `dec_prop_2` decimal(13,4) DEFAULT NULL,
  `bool_prop_1` varchar(1) DEFAULT NULL,
  `bool_prop_2` varchar(1) DEFAULT NULL,
  PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
  CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `qrtz_triggers` (`sched_name`, `trigger_name`, `trigger_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for qrtz_triggers
-- ----------------------------
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) DEFAULT NULL,
  `next_fire_time` bigint(13) DEFAULT NULL,
  `prev_fire_time` bigint(13) DEFAULT NULL,
  `priority` int(11) DEFAULT NULL,
  `trigger_state` varchar(16) NOT NULL,
  `trigger_type` varchar(8) NOT NULL,
  `start_time` bigint(13) NOT NULL,
  `end_time` bigint(13) DEFAULT NULL,
  `calendar_name` varchar(200) DEFAULT NULL,
  `misfire_instr` smallint(2) DEFAULT NULL,
  `job_data` blob,
  PRIMARY KEY (`sched_name`,`trigger_name`,`trigger_group`),
  KEY `sched_name` (`sched_name`,`job_name`,`job_group`),
  CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`sched_name`, `job_name`, `job_group`) REFERENCES `qrtz_job_details` (`sched_name`, `job_name`, `job_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for sys_job
-- ----------------------------
DROP TABLE IF EXISTS `sys_job`;
CREATE TABLE `sys_job` (
  `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID',
  `job_name` varchar(64) NOT NULL DEFAULT '' COMMENT '任务名称',
  `job_group` varchar(64) NOT NULL DEFAULT 'DEFAULT' COMMENT '任务组名',
  `invoke_target` varchar(500) NOT NULL COMMENT '调用目标字符串',
  `cron_expression` varchar(255) DEFAULT '' COMMENT 'cron执行表达式',
  `status` char(1) DEFAULT '0' COMMENT '状态(0正常 1暂停)',
  PRIMARY KEY (`job_id`,`job_name`,`job_group`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8 COMMENT='定时任务调度表';

4、通用配置类和工具类

调度任务数据源和参数配置类

任务信息存入数据库不易丢失。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * 定时任务配置
 */
@Configuration
public class ScheduleConfig{
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource){
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        // 数据源
        factory.setDataSource(dataSource);
        // quartz参数
        Properties prop = new Properties();
        prop.put("org.quartz.scheduler.instanceName", "CustomScheduler");
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        // 线程池配置
        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "20");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        // JobStore配置
        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        // 集群配置
        prop.put("org.quartz.jobStore.isClustered", "false");
        prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");

        // sqlserver 启用
        prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
        prop.put("org.quartz.jobStore.misfireThreshold", "12000");
        prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
        factory.setQuartzProperties(prop);

        factory.setSchedulerName("CustomScheduler");
        // 延时启动(单位:s)
        factory.setStartupDelay(5);
        factory.setApplicationContextSchedulerContextKey("applicationContextKey");
        // 可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        factory.setOverwriteExistingJobs(true);
        // 设置自动启动,默认为true
        factory.setAutoStartup(true);

        return factory;
    }
}

通用常量配置

/**
 * 通用常量
 */
public interface ScheduleConstants {
    /** 执行目标 */
    String TASK_NAME = "TASK_NAME";
    /** 执行目标 */
    String TASK_PARA = "TASK_PARA";
    /** 正常 */
    String NORMAL = "0";
    /** 暂停 */
    String PAUSE = "1";
}

Spring工具类

方便获取bean。

package com.quartz.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }
    /**
     * 获取applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     */
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     */
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     */
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}

5、调度任务相关类

调度任务初始化类

从数据库中加载任务信息,并创建。数据库使用mybatis-plus作为持久层,其相关类当前不做展示。

import com.quartz.domain.SysJob;
import com.quartz.mapper.SysJobMapper;
import com.quartz.util.QuartzJobUtil;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 项目启动时初始化调度任务
 */
@Component
public class JobCommandLineRunner implements CommandLineRunner {
    private final QuartzJobUtil quartzJobUtil;
    private final SysJobMapper jobMapper;

    public JobCommandLineRunner(SysJobMapper jobMapper, QuartzJobUtil quartzJobUtil) {
        this.jobMapper = jobMapper;
        this.quartzJobUtil = quartzJobUtil;
    }

    @Override
    public void run(String... args) throws Exception {
        quartzJobUtil.clear();
        List<SysJob> jobList = jobMapper.selectJobAll();
        for (SysJob job : jobList){
            quartzJobUtil.createScheduleJob(job);
        }
    }
}

调度任务操作实现类

包括创建、恢复、删除任务等操作。

package com.quartz.util;

import com.quartz.config.ScheduleConstants;
import com.quartz.domain.SysJob;
import com.quartz.task.CustomJobListener;
import com.quartz.task.QuartzJobExecutor;
import org.quartz.*;
import org.quartz.impl.matchers.EverythingMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import org.springframework.stereotype.Component;

/**
 * 定时任务工具类
 */
@Component
public class QuartzJobUtil {

    private final CustomJobListener customJobListener;
    private final Scheduler scheduler;

    public QuartzJobUtil(Scheduler scheduler, CustomJobListener customJobListener) {
        this.scheduler = scheduler;
        this.customJobListener = customJobListener;
    }

    /**
     * 清除定时任务
     */
    public void clear() throws SchedulerException {
        scheduler.clear();
    }

    /**
     * 恢复定时任务
     */
    public void resumeJob(Long jobId,String jobGroup) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(ScheduleConstants.TASK_NAME + jobId, jobGroup));
    }

    /**
     * 触发定时任务
     */
    public void triggerJob(Long jobId,String jobGroup,SysJob sysJob) throws SchedulerException {
        JobDataMap dataMap = new JobDataMap();
        dataMap.put(ScheduleConstants.TASK_PARA, sysJob);
        scheduler.triggerJob(JobKey.jobKey(ScheduleConstants.TASK_NAME + jobId, jobGroup), dataMap);
    }

    /**
     * 判断定时任务是否存在
     */
    public boolean checkExists(Long jobId,String jobGroup) throws SchedulerException {
        return scheduler.checkExists(JobKey.jobKey(ScheduleConstants.TASK_NAME + jobId, jobGroup));
    }

    /**
     * 删除定时任务
     */
    public void deleteJob(Long jobId, String jobGroup) throws SchedulerException {
        scheduler.deleteJob(JobKey.jobKey(ScheduleConstants.TASK_NAME + jobId, jobGroup));
    }

    /**
     * 暂停定时任务
     */
    public void pauseJob(Long jobId, String jobGroup) throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey(ScheduleConstants.TASK_NAME + jobId, jobGroup));
    }

    /**
     * 创建定时任务
     */
    public void createScheduleJob(SysJob job) throws Exception {
        Class<? extends Job> jobClass = QuartzJobExecutor.class;
        // 构建job信息
        Long jobId = job.getJobId();
        String jobGroup = job.getJobGroup();
        JobKey jobKey=JobKey.jobKey(ScheduleConstants.TASK_NAME + jobId, jobGroup);
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobKey).build();

        // 表达式调度构建器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

        // 按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(TriggerKey.triggerKey(ScheduleConstants.TASK_NAME + jobId, jobGroup))
                .withSchedule(cronScheduleBuilder).build();

        // 放入参数,业务执行时获取
        jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PARA, job);

        // 判断是否存在
        if (scheduler.checkExists(jobKey)){
            // 防止创建时存在数据问题 先移除,然后在执行创建操作
            scheduler.deleteJob(jobKey);
        }
        // 安排任务
        scheduler.scheduleJob(jobDetail, trigger);
        // 暂停任务
        if (job.getStatus().equals(ScheduleConstants.PAUSE)){
            scheduler.pauseJob(jobKey);
        }
//        // 全局任务监听器
//        scheduler.getListenerManager().addJobListener(new CustomJobListener(), EverythingMatcher.allJobs());
        // 局部任务监听器
        scheduler.getListenerManager().addJobListener(customJobListener, KeyMatcher.keyEquals(JobKey.jobKey(ScheduleConstants.TASK_NAME +2,jobGroup)));
    }
}

调度任务反射执行类

利用反射机制执行指定类的指定方法。

import com.quartz.config.ScheduleConstants;
import com.quartz.domain.SysJob;
import com.quartz.util.SpringUtil;
import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;

/**
 * 定时任务处理(@DisallowConcurrentExecution注解不允许并发执行)
 */
@DisallowConcurrentExecution
public class QuartzJobExecutor extends QuartzJobBean {

    /**
     * 反射执行
     */
    @Override
    protected void executeInternal(JobExecutionContext context) {
        // 获取之前存入的job信息
        SysJob sysJob = (SysJob)context.getMergedJobDataMap().get(ScheduleConstants.TASK_PARA);
        try {
            invokeMethod(sysJob);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 执行方法
     */
    private void invokeMethod(SysJob sysJob) throws Exception{
        // 解析实体名和方法名
        String invokeTarget = sysJob.getInvokeTarget();
        String beanName = getBeanName(invokeTarget);
        String methodName = getMethodName(invokeTarget);
        // 获取实体类和方法参数
        Object bean = SpringUtil.getBean(beanName);

        // 分有参和无参执行方法
        if (invokeTarget.contains("(")){
            // 参数值
            Object[] methodParams=params(invokeTarget);
            Method method = bean.getClass().getDeclaredMethod(methodName, classes(methodParams));
            method.invoke(bean, methodParams);
        }else{
            Method method = bean.getClass().getDeclaredMethod(methodName);
            method.invoke(bean);
        }
    }

    /**
     * 获取bean名称
     */
    private String getBeanName(String invokeTarget) {
        String beanName = StringUtils.substringBefore(invokeTarget, "(");
        return StringUtils.substringBeforeLast(beanName, ".");
    }

    /**
     * 获取bean方法
     */
    private String getMethodName(String invokeTarget) {
        String methodName = StringUtils.substringBefore(invokeTarget, "(");
        return StringUtils.substringAfterLast(methodName, ".");
    }

    /**
     * 获取参数值
     */
    private Object[] params(String invokeTarget){
        String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")").replace("'","");
        return methodStr.split(",");
    }

    /**
     * 获取参数类型
     */
    private Class<?>[] classes(Object[] methodParams){
        // 参数类型
        Class<?>[] classes = new Class<?>[methodParams.length];
        int index = 0;
        for (Object ignored : methodParams){
            classes[index] = String.class;
            index++;
        }
        return classes;
    }
}

调度任务执行监听类

可以监听调度任务执行的流程。

import com.quartz.config.ScheduleConstants;
import com.quartz.domain.SysJob;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.springframework.stereotype.Component;

/**
 * 定时任务监听
 */
@Component
public class CustomJobListener implements JobListener {
    @Override
    public String getName() {
        return this.getClass().getName();
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        SysJob sysJob = (SysJob)context.getMergedJobDataMap().get(ScheduleConstants.TASK_PARA);
        String name = sysJob.getInvokeTarget();
        System.out.println("即将调用的方法:"+name);
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {
        SysJob sysJob = (SysJob)context.getMergedJobDataMap().get(ScheduleConstants.TASK_PARA);
        String name = sysJob.getInvokeTarget();
        System.out.println("方法"+"'"+name+"'"+"被拒绝执行");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException e) {
        SysJob sysJob = (SysJob)context.getMergedJobDataMap().get(ScheduleConstants.TASK_PARA);
        String name = sysJob.getInvokeTarget();
        System.out.println("方法"+"'"+name+"'"+"执行完毕");
    }
}

调度任务存放类

用于存放调度任务

import org.springframework.stereotype.Component;

/**
 * 定时任务
 */
@Component
public class CustomTask {

    public void params(String params1,String params2){
        System.out.println("执行有参方法,参数:" + params1+","+params2);
    }

    public void noParams(){
        System.out.println("执行无参方法");
    }
}

6、例行测试

在最后一张表,即sys_job表中存入任务相关信息。
当前往数据库中存入两个任务,一个有参一个无参,其中有参方法params,每6秒执行一次,参数为param1param2,无参方法noParams每5秒执行一次。
在这里插入图片描述
启动SpringBoot。
可以看到两个任务开始循环执行。由于有参任务处于被监听状态(在创建任务处设置),所以打印出了有参方法的监听信息。
在这里插入图片描述

发布了82 篇原创文章 · 获赞 9 · 访问量 6155

猜你喜欢

转载自blog.csdn.net/weixin_43424932/article/details/105713034