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;

在这里插入图片描述

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

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现SpringBoot项目动态跑批定时任务,可以使用Spring自带的定时任务框架,结合数据库中存储的cron表达式实现。 具体步骤如下: 1.在pom.xml文件中引入spring-boot-starter-quartzspring-boot-starter-jdbc依赖。 2.在application.properties或application.yml中配置数据库连接信息。 3.创建一个Job类,实现Quartz的Job接口,并实现execute方法,该方法就是定时任务执行的业务逻辑。 4.创建一个JobDetail对象,表示一个具体的可执行的调度程序。 5.创建一个Trigger对象,表示触发Job执行的条件。 6.将JobDetail和Trigger注册到Scheduler中。 7.从数据库中读取cron表达式,更新Trigger的cron表达式。 8.启动Scheduler,定时任务即可开始执行。 示例代码如下: 1.依赖配置: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> ``` 2.application.properties配置: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # Quartz spring.quartz.job-store-type=jdbc ``` 3.Job类: ``` @Component public class MyJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 定时任务执行的业务逻辑 System.out.println("定时任务执行了"); } } ``` 4.创建JobDetail和Trigger对象: ``` @Autowired private MyJob myJob; @Autowired private Scheduler scheduler; public void startJob() throws SchedulerException { // 创建JobDetail对象 JobDetail jobDetail = JobBuilder.newJob(myJob.getClass()) .withIdentity("myJob", "group1") .build(); // 创建Trigger对象 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")) // 初始cron表达式 .build(); // 注册JobDetail和Trigger scheduler.scheduleJob(jobDetail, trigger); // 启动Scheduler scheduler.start(); } ``` 5.从数据库中读取cron表达式,更新Trigger的cron表达式: ``` public void updateTrigger(String cron) throws SchedulerException { // 获取Trigger TriggerKey triggerKey = TriggerKey.triggerKey("myTrigger", "group1"); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 更新cron表达式 trigger = trigger.getTriggerBuilder() .withSchedule(CronScheduleBuilder.cronSchedule(cron)) .build(); // 重新注册Trigger scheduler.rescheduleJob(triggerKey, trigger); } ``` 6.调用startJob方法启动定时任务,调用updateTrigger方法动态更新cron表达式即可。 注意事项: 1.定时任务执行时间间隔不宜设置过短,避免对系统造成过大的负担。 2.更新cron表达式时需要先获取Trigger对象,然后重新构建Trigger对象并重新注册到Scheduler中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值