springboot整合quartz实现定时任务,数据库获取cron表达式多动态多任务

springboot整合quartz实现定时任务,数据库获取cron表达式多动态多任务

1.pom 代码片.

    <!--springboot整合quartz实现动态定时任务-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.3.2</version>
        </dependency>

创建表 代码片.

CREATE TABLE `base_quartz_config` (
  `Id` varchar(64) COLLATE utf8_bin NOT NULL COMMENT 'id(项目id)',
  `QuartaName` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '任务名称',
  `QuartaGroup` varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '任务组',
  `Status` int(11) DEFAULT NULL COMMENT '状态(0-运行任务 1-暂停任务 )',
  `QuartzClass` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '类全名',
  `Remark` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '备注',
  `CreateuserId` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '创建人',
  `CreateuserName` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '创建人姓名',
  `Expression` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '表达式',
  `CreateTime` datetime DEFAULT NULL,
  PRIMARY KEY (`Id`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;

springboot整合quartz实现定时任务,数据库获取cron表达式多动态多任务_第1张图片

BaseQuartzConfig代码片.


package net.ourway.ics.entities;

import lombok.Data;
import java.util.Date;

@Data
public class BaseQuartzConfig{
    private String Id;
    private String QuartaName;
    private String QuartaGroup;
    private Integer Status;
    private String QuartzClass;
    private String Remark;
    private String CreateuserId;
    private String CreateuserName;
    private String Expression;
    private Date CreateTime;
}

MyJobFactory 代码片.


package net.ourway.ics.quartz;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

@Component
public class MyJobFactory extends AdaptableJobFactory {

    private final AutowireCapableBeanFactory capableBeanFactory;

    public MyJobFactory(AutowireCapableBeanFactory capableBeanFactory) {
        this.capableBeanFactory = capableBeanFactory;
    }

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        // 调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

MySchedulerFactory 代码片.


package net.ourway.ics.quartz;

import net.ourway.common.dingtalk.taobao.StringUtils;
import net.ourway.ics.entities.BaseQuartzConfig;
import net.ourway.ics.mappers.BaseQuartzMapper;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service("MySchedulerFactory")
@Component
public class MySchedulerFactory {

    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;

    /**
     * 任务配置读取服务
     */
    @Resource
    private BaseQuartzMapper baseQuartzMapper;

    public void scheduleJobs() throws SchedulerException {
        Scheduler scheduler = getScheduler();
        // 为了避免org.quartz.ObjectAlreadyExistsException,在执行前将scheduler进行清理
        scheduler.clear();
        startJob(scheduler);
    }

    /**
     * 获取scheduler
     */
    private Scheduler getScheduler() {
        return schedulerFactoryBean.getScheduler();
    }


    /**
     * 项目启动 开启任务
     * @param scheduler
     */
    private void startJob(Scheduler scheduler) {
        try {
            List<BaseQuartzConfig> jobList = baseQuartzMapper.findAll();
            for (BaseQuartzConfig config : jobList) {
                try {
                    // 1-暂停的任务 0-正常运行任务
                    if (1L == config.getStatus()) {
                        continue;
                    }
                    String classz = config.getQuartzClass();
                    if (!StringUtils.isEmpty(classz)) {
                        @SuppressWarnings("unchecked")
                        Class<? extends Job> clazz = (Class<? extends Job>) Class.forName(classz);
                        JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(config.getId(), config.getQuartaGroup())
                                .build();
                        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(config.getExpression());
                        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(config.getId(), config.getQuartaGroup())
                                .withSchedule(scheduleBuilder).build();
                        scheduler.scheduleJob(jobDetail, cronTrigger);
                    }
                } catch (Exception e) {
                    System.out.println("定时启动异常:" + config.getQuartaName() + " 异常信息:" + e.getMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 任务暂停
     *
     * @param id
     */
    public void pauseJob(String id) throws Exception {
        Scheduler scheduler = getScheduler();
        BaseQuartzConfig QuartzConfig = baseQuartzMapper.get(String.valueOf(id));
        JobKey jobKey = JobKey.jobKey(QuartzConfig.getId(), QuartzConfig.getQuartaGroup());
        scheduler.deleteJob(jobKey);
        baseQuartzMapper.update(id,1);
    }

    /**
     * 任务恢复
     *
     * @param id
     */
    public void resumeJob(String id) throws Exception {
        Scheduler scheduler = getScheduler();
        BaseQuartzConfig QuartzConfig = baseQuartzMapper.get(String.valueOf(id));
        JobKey jobKey = JobKey.jobKey(QuartzConfig.getId(), QuartzConfig.getQuartaGroup());
        Class<? extends Job> clazz = (Class<? extends Job>) Class.forName(QuartzConfig.getQuartzClass());
        JobDetail jobDetail1 = scheduler.getJobDetail(jobKey);
        if (jobDetail1 == null) {
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(QuartzConfig.getId(), QuartzConfig.getQuartaGroup())
                    .build();
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(QuartzConfig.getExpression());
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(QuartzConfig.getId(), QuartzConfig.getQuartaGroup())
                    .withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
            baseQuartzMapper.update(id,0);
        } else {
            scheduler.resumeJob(jobKey);
        }
    }

}

ScheduleTask 代码片.


package net.ourway.ics.quartz;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Configuration
@Component
@EnableScheduling
public class ScheduleTask implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        try {
            JobDetail jobDetail = jobExecutionContext.getJobDetail();
            String projectId = jobDetail.getKey().getName();
            System.out.println("调度任务:" + projectId + ",        "
                    + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            //逻辑内容-------------------------

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

StartSchedulerListener 代码片.

package net.ourway.ics.quartz;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class StartSchedulerListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    public MySchedulerFactory mySchedulerFactory;

    private final MyJobFactory myJobFactory;

    public StartSchedulerListener(MyJobFactory myJobFactory) {
        this.myJobFactory = myJobFactory;
    }

    // springboot 启动监听
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
            mySchedulerFactory.scheduleJobs();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    //注入SchedulerFactoryBean
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setStartupDelay(5);//延时5秒启动
        schedulerFactoryBean.setJobFactory(myJobFactory);
        return schedulerFactoryBean;
    }

    @Bean(name = "scheduler")
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }

}

新增一个定时任务 逻辑层代码 代码片.

	/*
	 * 新增一个定时任务
	*/
	//逻辑层代码
	public CallResult save(ProjectSubmitFormDTO entity) {
	    BaseQuartzConfig config = new BaseQuartzConfig();
	    config.setId(entity.getId());
	    config.setQuartaName(entity.getTitle());
	    config.setQuartaGroup(entity.getId());
	    config.setStatus(1);                                            //暂时不开启任务调度状态
	    config.setQuartzClass("net.ourway.ics.quartz.ScheduleTask");    //写死
	    config.setCreateuserId(entity.getCreatorId());
	    config.setCreateuserName(entity.getCreatorName());
	    config.setExpression(entity.getRepeatCron());
	    config.setCreateTime(new Date());
	    config.setRemark(Remark);
	    _BaseQuartzMapper.insert(config);
	
	    try {
           Thread.sleep(1000);
           schedulerFactory.resumeJob(entity.getId());     //开启任务调度
           
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
    }

参考:https://blog.csdn.net/weixin_42719412/article/details/103294403?spm=1001.2014.3001.5502

你可能感兴趣的:(Java,spring,boot,数据库,java)